From 53f39b99d541754030728d3ce99dc112797dfa38 Mon Sep 17 00:00:00 2001 From: Anton Sarukhanov <code@ant.sr> Date: Fri, 2 Nov 2018 00:17:03 -0400 Subject: [PATCH] Define ADC register constants, implement register access & sending commands. --- ads8698.c | 65 ++++++++++++++++++++++++++++++++--------------- include/ads8698.h | 49 ++++++++++++++++++++++++++++++++--- include/spi.h | 2 +- measure.c | 3 ++- spi.c | 6 ++--- 5 files changed, 96 insertions(+), 29 deletions(-) diff --git a/ads8698.c b/ads8698.c index 0591f2c..ffcc403 100644 --- a/ads8698.c +++ b/ads8698.c @@ -1,5 +1,5 @@ /** - * This file includes functions for interacting with an ADC + * This file includes functions for interacting with an ADC. * * Written for: TI ADS8698 8-channel ADC * @@ -34,42 +34,67 @@ void ADS8698_init(void) { // Reset the ADC. ADS8698_reset(); - - // Start measurements - ADS8698_send_command(ADS8698_RESET); - SPI_transmit('H'); - SPI_transmit('e'); - SPI_transmit('l'); - SPI_transmit('l'); - SPI_transmit('o'); - SPI_transmit('!'); } /* Set the input range on the ADC. */ void ADS8698_set_range(ADS8698_range range) { - // TODO - return; + uint8_t address; + for (uint8_t channel = 0; channel < 8; channel++) { + address = 0x05 + channel; + ADS8698_write_register(address, range); + ADS8698_read_register(address); + } } -/* Write to a register on the ADC. */ -void ADS8698_write_register(uint8_t address, uint8_t data) { - // TODO - return; +/* Start the ADC's auto-scan mode. */ +void ADS8698_auto_scan(void) { + return; // TODO } -/* Send a command to the ADC. */ +/* Send a command to the ADC. + * + * See datasheet section 8.5.1. + */ void ADS8698_send_command(ADS8698_command command) { - // TODO - return; + ADS8698_CS_LOW; + SPI_transmit(command); // First byte + SPI_transmit(0x00); // Second byte (always zero). + ADS8698_CS_HIGH; +} + +/* Write to a register on the ADC. + * + * See datasheet section 8.5.2. + */ +void ADS8698_write_register(uint8_t address, uint8_t data) { + ADS8698_CS_LOW; + address |= 1UL << 7; // 8th bit signifies "Read/Write Mode"; set 1. + SPI_transmit(address); + SPI_transmit(data); + ADS8698_CS_HIGH; } +/* Read from a register on the ADC. + * + * See datasheet section 8.5.2. + */ +uint8_t ADS8698_read_register(uint8_t address) { + ADS8698_CS_LOW; + address |= 0UL << 7; // 8th bit signifies "Read/Write Mode"; set 0. + SPI_transmit(address << 1); + uint8_t data = SPI_receive(); + ADS8698_CS_HIGH; + return data; +} + + /* Reset the ADC. * - * Pull RST low for 70ns (instructions: 40-100ns). * See datasheet section 8.4.1.1.6. */ void ADS8698_reset(void) { PORTC &= ~_BV(PORTC0); + // Pull RST low for 70ns (instructions: 40-100ns). _delay_us(0.47); PORTC |= _BV(PORTC0); } diff --git a/include/ads8698.h b/include/ads8698.h index 293a92d..b890efd 100644 --- a/include/ads8698.h +++ b/include/ads8698.h @@ -1,5 +1,5 @@ /** - * This file includes functions for interacting with an ADC + * This file includes functions for interacting with an ADC. * * Written for: TI ADS8698 8-channel ADC * @@ -14,7 +14,13 @@ */ -/* ADC Commands. +// Macros to toggle control pins +#define ADS8698_RST_LOW PORTC &= ~_BV(PORTC0) +#define ADS8698_RST_HIGH PORTC |= _BV(PORTC0) +#define ADS8698_CS_LOW PORTC &= ~_BV(PORTC1) +#define ADS8698_CS_HIGH PORTC |= _BV(PORTC1) + +/* ADC commands * * See datasheet section 8.5.1. */ @@ -36,7 +42,36 @@ typedef enum { } ADS8698_command; -/* ADC Input Ranges. +/* ADC program registers + * + * See datasheet section 8.5.1. + */ +typedef enum { + // Auto-Scan control + ADS8698_AUTO_CH_SEL = 0x01, // Channels to use in auto-scan mode + ADS8698_CH_POWER_DN = 0x02, // Channels to shut down + + // Feature selection + ADS8698_FEATURE_SEL = 0x03, // Enable & configure device features + + // Range selection + ADS8698_CH0_RANGE = 0x05, // Input range for channel 0 + ADS8698_CH1_RANGE = 0x06, // Input range for channel 1 + ADS8698_CH2_RANGE = 0x07, // Input range for channel 2 + ADS8698_CH3_RANGE = 0x08, // Input range for channel 3 + ADS8698_CH4_RANGE = 0x09, // Input range for channel 4 + ADS8698_CH5_RANGE = 0x0A, // Input range for channel 5 + ADS8698_CH6_RANGE = 0x0B, // Input range for channel 6 + ADS8698_CH7_RANGE = 0x0C, // Input range for channel 7 + + // TODO: Implement alarm-related registers. + + // Command read-back (read-only) + ADS8698_COMMAND = 0x00, // Current device command (mode of operation) +} ADS8698_register; + + +/* ADC input ranges * * See datasheet section 8.5.2.3.3. */ @@ -45,7 +80,7 @@ typedef enum { ADS8698_RANGE_BIPOLAR_1_25X = 0x01, // 0 +/- 1.25 x Vref ADS8698_RANGE_BIPOLAR_0_625X = 0x02, // 0 +/- 0.625 x Vref ADS8698_RANGE_UNIPOLAR_2_5X = 0x05, // 0 + 2.5 x Vref - ADS8698_RANGE_UNIPOLAR_1_25X = 0x0 // 0 + 1.25 x Vref + ADS8698_RANGE_UNIPOLAR_1_25X = 0x06 // 0 + 1.25 x Vref } ADS8698_range; @@ -58,5 +93,11 @@ void ADS8698_set_range(ADS8698_range range); /* Send a command to the ADC. */ void ADS8698_send_command(ADS8698_command command); +/* Write to a register on the ADC. */ +void ADS8698_write_register(uint8_t address, uint8_t data); + +/* Read from a register on the ADC. */ +uint8_t ADS8698_read_register(uint8_t address); + /* Reset the ADC. */ void ADS8698_reset(void); diff --git a/include/spi.h b/include/spi.h index 5bf901f..f0d0df8 100644 --- a/include/spi.h +++ b/include/spi.h @@ -9,4 +9,4 @@ void SPI_init(void); void SPI_transmit(char data); /* Receive a byte from the SPI interface. */ -char SPI_receive(void); +uint8_t SPI_receive(void); diff --git a/measure.c b/measure.c index c14a95b..eb61fc1 100644 --- a/measure.c +++ b/measure.c @@ -9,7 +9,7 @@ #include "include/ads8698.h" #include "include/measure.h" - +#define MEASURE_RANGE ADS8698_RANGE_UNIPOLAR_1_25X /* Acquire resistance measurements. */ struct Measurements measure() { @@ -22,6 +22,7 @@ struct Measurements measure() { /* Prepare for measuring resistance. */ void Measure_init(void) { ADS8698_init(); + ADS8698_set_range(MEASURE_RANGE); _delay_us(100); // int sample_count = 2048; // TODO: what is this // ADS8698_config(&sample_buffer, sample_count, ADS8698_CHANNEL_0, INPUT_RANGE_UNIPOLAR_1_25X_VREF); diff --git a/spi.c b/spi.c index e20d0c6..d11b552 100644 --- a/spi.c +++ b/spi.c @@ -11,8 +11,8 @@ void SPI_init(void) { // Set MOSI, SCK, and SS as outputs DDRB = (1<<DDB3) | (1<<DDB5) | (1<<DDB2); - // Enable SPI, become master, set clock rate to CPU clock / 16. - SPCR = (1<<SPE) | (1<<MSTR); + // Enable SPI, become master, set SPI clock rate to 1 MHz. + SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0); } /* Send a byte over the SPI interface. */ @@ -26,7 +26,7 @@ void SPI_transmit(char data) { } /* Receive a byte from the SPI interface. */ -char SPI_receive(void) { +uint8_t SPI_receive(void) { // Wait for reception to complete. while (!(SPSR & (1<<SPIF))) ; -- GitLab