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