Skip to content
Snippets Groups Projects
Commit 53f39b99 authored by Anton Sarukhanov's avatar Anton Sarukhanov
Browse files

Define ADC register constants, implement register access & sending commands.

parent 59c4103f
No related branches found
No related tags found
No related merge requests found
/** /**
* 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 * Written for: TI ADS8698 8-channel ADC
* *
...@@ -34,42 +34,67 @@ void ADS8698_init(void) { ...@@ -34,42 +34,67 @@ void ADS8698_init(void) {
// Reset the ADC. // Reset the ADC.
ADS8698_reset(); 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. */ /* Set the input range on the ADC. */
void ADS8698_set_range(ADS8698_range range) { void ADS8698_set_range(ADS8698_range range) {
// TODO uint8_t address;
return; 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. */ /* Start the ADC's auto-scan mode. */
void ADS8698_write_register(uint8_t address, uint8_t data) { void ADS8698_auto_scan(void) {
// TODO return; // TODO
return;
} }
/* 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) { void ADS8698_send_command(ADS8698_command command) {
// TODO ADS8698_CS_LOW;
return; 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. /* Reset the ADC.
* *
* Pull RST low for 70ns (instructions: 40-100ns).
* See datasheet section 8.4.1.1.6. * See datasheet section 8.4.1.1.6.
*/ */
void ADS8698_reset(void) { void ADS8698_reset(void) {
PORTC &= ~_BV(PORTC0); PORTC &= ~_BV(PORTC0);
// Pull RST low for 70ns (instructions: 40-100ns).
_delay_us(0.47); _delay_us(0.47);
PORTC |= _BV(PORTC0); PORTC |= _BV(PORTC0);
} }
/** /**
* 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 * Written for: TI ADS8698 8-channel ADC
* *
...@@ -14,7 +14,13 @@ ...@@ -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. * See datasheet section 8.5.1.
*/ */
...@@ -36,7 +42,36 @@ typedef enum { ...@@ -36,7 +42,36 @@ typedef enum {
} ADS8698_command; } 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. * See datasheet section 8.5.2.3.3.
*/ */
...@@ -45,7 +80,7 @@ typedef enum { ...@@ -45,7 +80,7 @@ typedef enum {
ADS8698_RANGE_BIPOLAR_1_25X = 0x01, // 0 +/- 1.25 x Vref ADS8698_RANGE_BIPOLAR_1_25X = 0x01, // 0 +/- 1.25 x Vref
ADS8698_RANGE_BIPOLAR_0_625X = 0x02, // 0 +/- 0.625 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_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; } ADS8698_range;
...@@ -58,5 +93,11 @@ void ADS8698_set_range(ADS8698_range range); ...@@ -58,5 +93,11 @@ void ADS8698_set_range(ADS8698_range range);
/* Send a command to the ADC. */ /* Send a command to the ADC. */
void ADS8698_send_command(ADS8698_command command); 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. */ /* Reset the ADC. */
void ADS8698_reset(void); void ADS8698_reset(void);
...@@ -9,4 +9,4 @@ void SPI_init(void); ...@@ -9,4 +9,4 @@ void SPI_init(void);
void SPI_transmit(char data); void SPI_transmit(char data);
/* Receive a byte from the SPI interface. */ /* Receive a byte from the SPI interface. */
char SPI_receive(void); uint8_t SPI_receive(void);
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include "include/ads8698.h" #include "include/ads8698.h"
#include "include/measure.h" #include "include/measure.h"
#define MEASURE_RANGE ADS8698_RANGE_UNIPOLAR_1_25X
/* Acquire resistance measurements. */ /* Acquire resistance measurements. */
struct Measurements measure() { struct Measurements measure() {
...@@ -22,6 +22,7 @@ struct Measurements measure() { ...@@ -22,6 +22,7 @@ struct Measurements measure() {
/* Prepare for measuring resistance. */ /* Prepare for measuring resistance. */
void Measure_init(void) { void Measure_init(void) {
ADS8698_init(); ADS8698_init();
ADS8698_set_range(MEASURE_RANGE);
_delay_us(100); _delay_us(100);
// int sample_count = 2048; // TODO: what is this // int sample_count = 2048; // TODO: what is this
// ADS8698_config(&sample_buffer, sample_count, ADS8698_CHANNEL_0, INPUT_RANGE_UNIPOLAR_1_25X_VREF); // ADS8698_config(&sample_buffer, sample_count, ADS8698_CHANNEL_0, INPUT_RANGE_UNIPOLAR_1_25X_VREF);
......
...@@ -11,8 +11,8 @@ void SPI_init(void) { ...@@ -11,8 +11,8 @@ void SPI_init(void) {
// Set MOSI, SCK, and SS as outputs // Set MOSI, SCK, and SS as outputs
DDRB = (1<<DDB3) | (1<<DDB5) | (1<<DDB2); DDRB = (1<<DDB3) | (1<<DDB5) | (1<<DDB2);
// Enable SPI, become master, set clock rate to CPU clock / 16. // Enable SPI, become master, set SPI clock rate to 1 MHz.
SPCR = (1<<SPE) | (1<<MSTR); SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);
} }
/* Send a byte over the SPI interface. */ /* Send a byte over the SPI interface. */
...@@ -26,7 +26,7 @@ void SPI_transmit(char data) { ...@@ -26,7 +26,7 @@ void SPI_transmit(char data) {
} }
/* Receive a byte from the SPI interface. */ /* Receive a byte from the SPI interface. */
char SPI_receive(void) { uint8_t SPI_receive(void) {
// Wait for reception to complete. // Wait for reception to complete.
while (!(SPSR & (1<<SPIF))) while (!(SPSR & (1<<SPIF)))
; ;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment