KingXerxes512
Member
Hello, I am trying to use the MCP3464 chip to sample arbitrary waveforms in a larger project, but right now I am just trying to get the chip sampling. I am not able to get any meaningful output.
I am using a Teensy 4.1 which claims to be able to use up to 20 MHz but I'm not trying to push its limits so using a 100kHz clock right now for debugging and cleaner waveforms.
Using my oscilloscope to view the SPI waveforms, the waveforms being sent to the chip look exactly as I would expect them to, but the MISO signal does not look remotely correct and thus my MCU says it only gets 0 back for every sample.
All four SPI Lines Image:
Yellow - Chip Select
Blue - SCLK
Purple - MOSI
Green - MISO
I am using a Teensy 4.1 which claims to be able to use up to 20 MHz but I'm not trying to push its limits so using a 100kHz clock right now for debugging and cleaner waveforms.
Using my oscilloscope to view the SPI waveforms, the waveforms being sent to the chip look exactly as I would expect them to, but the MISO signal does not look remotely correct and thus my MCU says it only gets 0 back for every sample.
All four SPI Lines Image:
Yellow - Chip Select
Blue - SCLK
Purple - MOSI
Green - MISO
Code:
#include <SPI.h>
#define SPI_CLK 100000 // 100 kHz
#define CHIP_SELECT 10
// Register definitions
#define REG_ADCDATA 0x00
#define REG_CONFIG0 0x01
#define REG_CONFIG1 0x02
#define REG_CONFIG2 0x03
#define REG_CONFIG3 0x04
#define REG_IRQ 0x05
#define REG_MUX 0x06
#define REG_SCAN 0x07
#define REG_TIMER 0x08
#define REG_OFFSETCAL 0x09
#define REG_GAINCAL 0x0A
#define REG_LOCK 0x0D
// Init Vectors
#define CONFIG0_INIT 0b11110011 // No total shutdown, internal clock present on pin 18, 0uA current source, ADC conversion mode
#define CONFIG1_INIT 0b00001100 // No prescaler value on clock, over sampling ratio = 256 (default)
#define CONFIG2_INIT 0b10001011 // 1x current boost, 1x Gain, auto zeroing disabled
#define CONFIG3_INIT 0b11000000 // Continuous conversion mode, 16 bit, crc-16 only, crc on communication disabled, offset calibration disabled, gain disabled
#define IRQ_INIT 0b00000110 // Fast commands enabled, IRQs enabled (although not used)
#define MUX_INIT 0b00000001 // Channel 0 -> +, Channel 1 -> -
// MCP3464R Byte Commands
#define CONV_START_FAST_COMM 0b01101000 // restarts ADC conversion, ADC_MODE = 11
#define STANDBY_MODE_FAST_COMM 0b01101100 // puts ADC into standby mode (no conversions, same power draw) ADC_MODE = 10
#define SHUTDOWN_MODE_FAST_COMM 0b01110000 // puts ADC into partial shutdown mode, ADC_MODE = 00
#define FULL_SHUTDOWN_FAST_COMM 0b01110100 // Puts ADC into full shutdown mode (essentially 0 current) CONFIG0 = 0x00
#define STATIC_READ 0b01000001 // must be |'ed with register address << 2
#define INCREMENTAL_READ 0b01000011 // must be |'ed with register address << 2
#define INCREMENTAL_WRITE 0b01000010 // must be |'ed with register address << 2
#define SPI_SETTINGS SPISettings(SPI_CLK, MSBFIRST, SPI_MODE0)
volatile uint8_t status = 0x00;
void sendFastCommand(uint8_t fastCommand) {
SPI.beginTransaction(SPI_SETTINGS);
digitalWrite(CHIP_SELECT, LOW);
SPI.transfer(fastCommand);
digitalWrite(CHIP_SELECT, HIGH);
SPI.endTransaction();
}
void writeByteToRegisterWithAddress(uint8_t address, uint8_t data) {
uint8_t commandByte = INCREMENTAL_WRITE | (address << 2);
SPI.beginTransaction(SPI_SETTINGS);
digitalWrite(CHIP_SELECT, LOW);
status = SPI.transfer(commandByte);
SPI.transfer(data);
digitalWrite(CHIP_SELECT, HIGH);
SPI.endTransaction();
}
uint8_t readByteFromRegisterWithAddress(uint8_t address) {
uint8_t commandByte = STATIC_READ | (address << 2);
SPI.beginTransaction(SPI_SETTINGS);
digitalWrite(CHIP_SELECT, LOW);
status = SPI.transfer(commandByte);
uint8_t byte = SPI.transfer(0);
digitalWrite(CHIP_SELECT, HIGH);
SPI.endTransaction();
return byte;
}
uint16_t readADC_DATA() {
uint8_t commandByte = STATIC_READ; // | (ADC_DATA_ADDR << 2); This code is left out since ADC_DATA_ADDR = 0x00
SPI.beginTransaction(SPI_SETTINGS);
digitalWrite(CHIP_SELECT, LOW);
status = SPI.transfer(commandByte);
uint16_t sample = SPI.transfer16(0);
digitalWrite(CHIP_SELECT, HIGH);
SPI.endTransaction();
//sendFastCommand(CONV_START_FAST_COMM);
return sample;
}
void initializeADC() {
writeByteToRegisterWithAddress(REG_CONFIG0, CONFIG0_INIT);
writeByteToRegisterWithAddress(REG_CONFIG2, CONFIG2_INIT);
writeByteToRegisterWithAddress(REG_CONFIG3, CONFIG3_INIT);
writeByteToRegisterWithAddress(REG_IRQ, IRQ_INIT);
writeByteToRegisterWithAddress(REG_MUX, MUX_INIT);
}
void setup() {
Serial.begin(250000);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB
}
Serial.println("Serial Connection Established!");
SPI.begin();
delay(1000);
initializeADC();
//sendFastCommand(CONV_START_FAST_COMM);
}
void loop() {
uint16_t temp = readADC_DATA();
Serial.print("value: ");
Serial.println(temp);
delay(25);
}