Browse Source

write adc stuff.. and remove hack from uart.c

git-svn-id: https://bucket.mit.edu/svn/nilm/zoom@5463 ddd99763-3ecb-0310-9145-efcb8ce7c51f
tags/zoom-1.0
jim 16 years ago
parent
commit
0c38ac8b7a
6 changed files with 101 additions and 10 deletions
  1. +93
    -7
      firmware/adc.c
  2. +2
    -0
      firmware/config.h
  3. +4
    -1
      firmware/dac.c
  4. +1
    -1
      firmware/dac.h
  5. +1
    -1
      firmware/uart.c
  6. BIN
      firmware/zoom.mcw

+ 93
- 7
firmware/adc.c View File

@@ -1,17 +1,103 @@
#include "config.h"
#include "adc.h"
/* The ADC (AD7846) is tricky, as new conversions start
automatically when the previous data read finishes.
To allow more control over start/read, we stretch the
read indefinitely by delaying the final SCK edge.
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
interrupt notification if desired */
#define TRIS_SDO TRISEbits.TRISE7
#define R_SDO PORTEbits.RE7
#define TRIS_SCK TRISEbits.TRISE6
#define LAT_SCK LATEbits.LATE6
/* Short delays */
#define wait_200ns() do { \
nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); \
} while(0)
#define wait_25ns() nop()
/* Initialize ADC */
void adc_init(void)
{
// TODO (SPI)
int i;
TRIS_SDO = 1;
LAT_SCK = 0;
TRIS_SCK = 0;
/* Startup delay CS down to SCK high t4 = 5000ns */
for (i = 0; i < 5000 / 25; i++)
wait_25ns();
/* Trigger a dummy read so we're prepared for the
next conversion */
(void) adc_read();
}
/* 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. */
uint32_t adc_read(void)
{
// TODO.
// can we separate read/start conversion?
// unclear
}
uint32_t val;
int i;
/* Start conversion by completing previous read */
LAT_SCK = 0;
/* Wait tKQMAX for SCK down to SDO valid */
wait_200ns();
/* Wait for conversion to finish */
while (R_SDO == 1)
continue;
/* Read it out */
val = 0;
for (i = 0; i < 32; i++) {
/* SCK low tLESCK = 25ns */
wait_25ns();
LAT_SCK = 1;
/* SCK high tHESCK = 25ns, but
we also have SCK down to SDO valid tKQMAX = 200ns?
Probably misspecified but wait tKQMAX anyway. */
wait_200ns();
val <<= 1;
if (R_SDO)
val |= 1;
/* Leave SCK high on final bit to delay new conversion */
if (i < 31)
LAT_SCK = 0;
}
/* Done */
return val;
}
/* Start a new conversion. If a conversion was already started
but the result was not read, this does nothing. */
void adc_start_conversion(void)
{
/* Start conversion by completing previous read */
LAT_SCK = 0;
/* Wait tKQMAX for SCK down to SDO valid in case we
call adc_is_conversion_finished right away. */
wait_200ns();
}
/* Return 1 if a conversion is in progress, 0 otherwise */
int adc_is_conversion_finished(void)
{
if (LAT_SCK == 0 && R_SDO == 1)
return 1;
return 0;
}

+ 2
- 0
firmware/config.h View File

@@ -14,5 +14,7 @@ typedef unsigned long int uint32_t;

void config_init(void);

#define nop() __asm("nop")

#endif


+ 4
- 1
firmware/dac.c View File

@@ -3,10 +3,13 @@
void dac_init(void)
{
/* data bus on port D */
TRISD = 0;
TRISEbits.TRISE0 = 0;
// TODO
}
void dac_write(uint16_t val)
{
// TODO
}
}

+ 1
- 1
firmware/dac.h View File

@@ -1,7 +1,7 @@
#ifndef DAC_H
#define DAC_H
#include <stdint.h>
#include "config.h"
void dac_init(void);
void dac_write(uint16_t val);


+ 1
- 1
firmware/uart.c View File

@@ -8,7 +8,7 @@ void uart_init(int uart, int32_t rate)
brg = ((FCY + (8 * rate - 1)) / (16 * rate)) - 1;
if (brg < 1) brg = 1;
if (brg > 65535) brg = hacked by chinese 65535;
if (brg > 65535) brg = 65535;

if (uart == 1) {
U1MODE = 0;


BIN
firmware/zoom.mcw View File


Loading…
Cancel
Save