66 lines
1.1 KiB
C
66 lines
1.1 KiB
C
#include "config.h"
|
|
#include "adc.h"
|
|
#include "timer.h"
|
|
|
|
/* Currently using software SPI because it's easy.
|
|
Consider using hardware SPI with DMA on a timer, though. */
|
|
|
|
#define TRIS_SDATA TRISFbits.TRISF7
|
|
#define R_SDATA PORTFbits.RF7
|
|
#define TRIS_SCLK TRISFbits.TRISF6
|
|
#define LAT_SCLK LATFbits.LATF6
|
|
#define TRIS_CS TRISBbits.TRISB2
|
|
#define LAT_CS LATBbits.LATB2
|
|
|
|
void adc_init(void)
|
|
{
|
|
TRIS_SDATA = 1;
|
|
LAT_CS = IO_HIGH;
|
|
TRIS_CS = 0;
|
|
LAT_SCLK = IO_HIGH;
|
|
TRIS_SCLK = 0;
|
|
}
|
|
|
|
int16_t adc_get(void)
|
|
{
|
|
uint16_t v = 0;
|
|
int i;
|
|
|
|
LAT_CS = IO_LOW;
|
|
for (i = 0; i < 16; i++) {
|
|
v <<= 1;
|
|
if (R_SDATA == IO_HIGH)
|
|
v |= 1;
|
|
LAT_SCLK = IO_LOW;
|
|
nop(); nop(); nop();
|
|
LAT_SCLK = IO_HIGH;
|
|
}
|
|
LAT_CS = IO_HIGH;
|
|
|
|
/* Sign-extend the 12-bit value */
|
|
if (v & 0x0800)
|
|
v |= 0xF000;
|
|
else
|
|
v &= ~0xF000;
|
|
return (int16_t) v;
|
|
}
|
|
|
|
uint16_t adc_get_raw(void)
|
|
{
|
|
uint16_t v = 0;
|
|
int i;
|
|
|
|
LAT_CS = IO_LOW;
|
|
for (i = 0; i < 16; i++) {
|
|
v <<= 1;
|
|
if (R_SDATA == IO_HIGH)
|
|
v |= 1;
|
|
LAT_SCLK = IO_LOW;
|
|
nop(); nop(); nop();
|
|
LAT_SCLK = IO_HIGH;
|
|
}
|
|
LAT_CS = IO_HIGH;
|
|
|
|
return (uint16_t) v;
|
|
}
|