Browse Source

ADC seems to work now.

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-efcb8ce7c51f
tags/zoom-1.0
jim 16 years ago
parent
commit
458c1e9ed1
6 changed files with 94 additions and 16 deletions
  1. +36
    -9
      firmware/adc.c
  2. +14
    -2
      firmware/adc.h
  3. +12
    -4
      firmware/uart.c
  4. +3
    -1
      firmware/uart.h
  5. +29
    -0
      firmware/zoom.c
  6. BIN
      firmware/zoom.mcw

+ 36
- 9
firmware/adc.c View File

@@ -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;
}

+ 14
- 2
firmware/adc.h View File

@@ -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

+ 12
- 4
firmware/uart.c View File

@@ -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;
}
}


+ 3
- 1
firmware/uart.h View File

@@ -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)


+ 29
- 0
firmware/zoom.c View File

@@ -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;
}

BIN
firmware/zoom.mcw View File


Loading…
Cancel
Save