Bug: CS High on first readADCx
I have ported the code for the raspberry pi pico, which is working fine, but I discovered a bug on the first read of the ADC.
Root of the problem is the ADS126X::writeRegister() command that is being executed once, resulting in the first _ads126x_spi_rw() command being executed after CS pin is pulled high by the writeRegister() command.
I have recorded the behaviour in the following with a logic analyzer:
A fix would be to move line 68 in ADS126X.cpp below the ADS126X::writeRegister() command in line 88 like this:
int32_t ADS126X::readADC1(uint8_t pos_pin,uint8_t neg_pin) {
// create buffer to hold transmission uint8_t buff[10] = {0}; // plenty of room, all zeros
union { // create a structure to hold all the data struct { uint32_t DATA4:8; // bits 0.. 7 uint32_t DATA3:8; // bits 8.. 15 uint32_t DATA2:8; // bits 16.. 23 uint32_t DATA1:8; // bits 24.. 31 } bit; uint32_t reg; } ADC_BYTES; ADC_BYTES.reg = 0; // clear the ram just in case
// check if desired pins are different than old pins if((REGISTER.INPMUX.bit.MUXN != neg_pin) || (REGISTER.INPMUX.bit.MUXP != pos_pin)) { REGISTER.INPMUX.bit.MUXN = neg_pin; REGISTER.INPMUX.bit.MUXP = pos_pin; ADS126X::writeRegister(ADS126X_INPMUX); // replace on ads126x }
if(cs_used) _ads126x_write_pin_low(cs_pin);
uint8_t i = 0; // current place in outgoing buffer buff[i] = ADS126X_RDATA1; // the read adc1 command i++;
if(REGISTER.INTERFACE.bit.STATUS) i++; // place to hold status byte i += 4; // place to hold adc data if(REGISTER.INTERFACE.bit.CRC>0) i++; // place to hold checksum/crc byte
_ads126x_spi_rw(buff,i); // write spi, save values on buff
uint8_t j = 1; // start at byte 1, either status or first adc value
if(REGISTER.INTERFACE.bit.STATUS) { // if status is being read STATUS.reg = buff[j]; // save status byte j++; // increment position counter }
// save the data bytes ADC_BYTES.bit.DATA1 = buff[j]; j++; ADC_BYTES.bit.DATA2 = buff[j]; j++; ADC_BYTES.bit.DATA3 = buff[j]; j++; ADC_BYTES.bit.DATA4 = buff[j]; j++;
if(REGISTER.INTERFACE.bit.CRC==ADS126X_CHECKSUM) { uint8_t checkbyte = buff[j]; CHECKSUM = ADS126X::find_checksum(ADC_BYTES.reg,checkbyte); } else if(REGISTER.INTERFACE.bit.CRC==ADS126X_CHECK_CRC) { uint8_t checkbyte = buff[j]; CHECKSUM = ADS126X::find_crc(ADC_BYTES.reg,checkbyte); }
if(cs_used) _ads126x_write_pin_high(cs_pin); return ADC_BYTES.reg; }
ADS126X::readADC2() can be fixed likewise.