Added adc_convert to give us a nice signed 32 bit value as the result. git-svn-id: https://bucket.mit.edu/svn/nilm/zoom@5470 ddd99763-3ecb-0310-9145-efcb8ce7c51ftags/zoom-1.0
@@ -8,13 +8,18 @@ | |||
This means we can't have the hardware do SPI for us. */ | |||
/* External serial clock, 2-wire I/O -- tie /EXT low, | |||
tie SDI for rate selection, tie /CS low, use BUSY for | |||
tie ADC SDI for rate selection, tie /CS low, use BUSY for | |||
interrupt notification if desired */ | |||
#define TRIS_SDO TRISEbits.TRISE7 | |||
#define R_SDO PORTEbits.RE7 | |||
#define TRIS_SCK TRISEbits.TRISE6 | |||
#define LAT_SCK LATEbits.LATE6 | |||
/* Since the ADC is 5v, ADC SDO must be on a digital-only pin. | |||
All exposed pins on B D and E are digital, so use SPI pins: | |||
ADC SDO = PIC SDI1 = RF7 | |||
ADC SCK = PIC SCK1 = RF6 | |||
*/ | |||
#define TRIS_SDO TRISFbits.TRISF7 | |||
#define R_SDO PORTFbits.RF7 | |||
#define TRIS_SCK TRISFbits.TRISF6 | |||
#define LAT_SCK LATFbits.LATF6 | |||
/* Short delays */ | |||
#define wait_200ns() do { \ | |||
@@ -42,7 +47,7 @@ void adc_init(void) | |||
/* Start a conversion if it hasn't already been started. | |||
Wait for conversion to finish. | |||
Read the result. */ | |||
Read the result and return the raw 32-bit value. */ | |||
uint32_t adc_read(void) | |||
{ | |||
uint32_t val; | |||
@@ -82,10 +87,32 @@ uint32_t adc_read(void) | |||
return val; | |||
} | |||
/* Convert a raw 32-bit value into a signed 32-bit result. | |||
The return value is full int32 range but only the high | |||
24 should be significant (low 3 will always be 0) */ | |||
int32_t adc_convert(uint32_t raw) | |||
{ | |||
int sigmsb = (raw >> 28) & 3; | |||
/* If SIG & MSB, it is a positive overflow */ | |||
if (sigmsb == 3) | |||
return (int32_t)0x7FFFFFFFL; | |||
/* If !SIG & !MSB, it is a negative overflow */ | |||
if (sigmsb == 0) | |||
return (int32_t)0x80000000L; | |||
/* Shift over EOC,DMY,SIG and return */ | |||
return ((int32_t)(raw << 3)); | |||
} | |||
/* Start a new conversion. If a conversion was already started | |||
but the result was not read, this does nothing. */ | |||
void adc_start_conversion(void) | |||
{ | |||
/* If we had a previous conversion ready to read, | |||
read it out so we can start a new conversion instead */ | |||
if (adc_is_conversion_ready()) | |||
(void) adc_read(); | |||
/* Start conversion by completing previous read */ | |||
LAT_SCK = 0; | |||
@@ -94,10 +121,10 @@ void adc_start_conversion(void) | |||
wait_200ns(); | |||
} | |||
/* Return 1 if a conversion is in progress, 0 otherwise */ | |||
int adc_is_conversion_finished(void) | |||
/* Return 1 if a conversion is finished and ready to be read, 0 otherwise */ | |||
int adc_is_conversion_ready(void) | |||
{ | |||
if (LAT_SCK == 0 && R_SDO == 1) | |||
if (LAT_SCK == 0 && R_SDO == 0) | |||
return 1; | |||
return 0; | |||
} |
@@ -4,8 +4,20 @@ | |||
/* Initialize ADC */ | |||
void adc_init(void); | |||
/* Read the result of the previous | |||
conversion and start a new one */ | |||
/* Start a conversion if it hasn't already been started. | |||
Wait for conversion to finish. | |||
Read the result and return the raw 32-bit value. */ | |||
uint32_t adc_read(void); | |||
/* Convert a raw 32-bit value into a signed result. | |||
The return value range is -(2^23) to (2^23)-1 */ | |||
int32_t adc_convert(uint32_t raw); | |||
/* Start a new conversion. If a conversion was already started | |||
but the result was not read, this does nothing. */ | |||
void adc_start_conversion(void); | |||
/* Return 1 if a conversion is in progress, 0 otherwise */ | |||
int adc_is_conversion_ready(void); | |||
#endif |
@@ -90,15 +90,23 @@ void uart_put_hex32(int uart, uint32_t x) | |||
uart_put_hex(uart, (x) & 0xFF); | |||
} | |||
void uart_put_dec(int uart, uint32_t x) | |||
void uart_put_dec(int uart, int32_t x) | |||
{ | |||
uint32_t val; | |||
uint32_t place = 1; | |||
while (x / place > 9) | |||
if (x > 0) { | |||
val = x; | |||
} else { | |||
uart_put(uart, '-'); | |||
val = -x; | |||
} | |||
while (val / place > 9) | |||
place *= 10; | |||
while (place > 0) { | |||
uart_put(uart, x / place + '0'); | |||
x %= place; | |||
uart_put(uart, val / place + '0'); | |||
val %= place; | |||
place /= 10; | |||
} | |||
} | |||
@@ -14,7 +14,7 @@ void uart_put_hex(int uart, uint8_t x); | |||
void uart_put_hex16(int uart, uint16_t x); | |||
void uart_put_hex32(int uart, uint32_t x); | |||
void uart_put_bin(int uart, uint8_t x); | |||
void uart_put_dec(int uart, uint32_t x); | |||
void uart_put_dec(int uart, int32_t x); | |||
/* Blocking receives */ | |||
uint8_t uart_get(int uart); | |||
@@ -25,6 +25,7 @@ int uart_can_put(int uart); | |||
/* Helpers to work with a specific uart */ | |||
#define uart1_init(x) uart_init(1, x) | |||
#define uart1_get() uart_get(1) | |||
#define uart1_put(x) uart_put(1,x) | |||
#define uart1_put_string(x) uart_put_string(1,x) | |||
#define uart1_crlf() uart_crlf(1) | |||
@@ -35,6 +36,7 @@ int uart_can_put(int uart); | |||
#define uart1_put_dec(x) uart_put_dec(1,x) | |||
#define uart2_init(x) uart_init(2, x) | |||
#define uart2_get() uart_get(2) | |||
#define uart2_put(x) uart_put(2,x) | |||
#define uart2_put_string(x) uart_put_string(2,x) | |||
#define uart2_crlf() uart_crlf(2) | |||
@@ -1,13 +1,42 @@ | |||
#include "config.h" | |||
#include "adc.h" | |||
#include "uart.h" | |||
#include <stdio.h> | |||
int main(void) | |||
{ | |||
uint32_t v; | |||
config_init(); | |||
uart1_init(115200); | |||
adc_init(); | |||
uart1_put_string("ADC test\r\n"); | |||
for(;;) { | |||
switch(uart1_get()) { | |||
case 'r': | |||
uart1_put_string("read"); | |||
v = adc_read(); | |||
uart1_put_string(" 0x"); | |||
uart1_put_hex32(v); | |||
v = adc_convert(v); | |||
uart1_put_string(" 0x"); | |||
uart1_put_hex32(v); | |||
uart1_put_string(" "); | |||
uart1_put_dec(v); | |||
uart1_put_string("\r\n"); | |||
break; | |||
case 'c': | |||
uart1_put_string("convert"); | |||
adc_start_conversion(); | |||
while (!adc_is_conversion_ready()) | |||
uart1_put('.'); | |||
uart1_put_string("done\r\n"); | |||
break; | |||
default: | |||
uart1_put_string("choose: Read Convert\r\n"); | |||
break; | |||
} | |||
} | |||
return 0; | |||
} |