Reputation: 3
I've come here as a last resort.
I'm using this MCP3561 with no external clock(MCLK) and not using the interrupt(irq) (both floating).
DATASHEET
I originally tried to run the fast command to get the adcdata but it came back all 0.
I then tried to to set up all the config bits accordingly and still when reading the adcdata back it returns all 0's for the data. But on the read all address's incrementally I can see the data from the config's just fine.
t_buf[0] = 0b01110110; //slaveaddr + lockregister + wr
t_buf[1] = 0b10100101; // wr 0xa5 to unlock writing to registers
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 0);
HAL_SPI_Transmit(&hspi1, t_buf, 2, 1000); //unlock resgisters
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 1);
t_buf[0] = 0b01000110; //slave address - reg address - write
t_buf[1] = 0b01100011; //config 0
t_buf[2] = 0b00011100; //config 1
t_buf[3] = 0b10101011; //config 2
t_buf[4] = 0b11000000; //config 3 - bit 4-5 is data_format[1:0]
t_buf[5] = 0b00100000; //irq register
t_buf[6] = 0b00000001; //mux
t_buf[7] = 0b00000000; //7-8-9 scan register
t_buf[8] = 0b00000000;
t_buf[9] = 0b00000000;
t_buf[10] = 0b00000000; //10-11-12 timer delay value
t_buf[11] = 0b00000000;
t_buf[12] = 0b00000000;
t_buf[13] = 0b00000000; //13-14-15 offset calibration
t_buf[14] = 0b00000000;
t_buf[15] = 0b00000000;
t_buf[16] = 0b10000000; //16-17-18 gain calibration //0x80 is default 1x gain
t_buf[17] = 0b00000000;
t_buf[18] = 0b00000000;
t_buf[19] = 0b10010000; //19-20-21 reserved should be set at 0x90
t_buf[20] = 0b00000000;
t_buf[21] = 0b00000000;
t_buf[22] = 0b01010000; // reserved set at 0x50
t_buf[23] = 0b00000000; // lock register 0xa5 unlock anything else lock
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 0);
HAL_SPI_Transmit(&hspi1, t_buf, 23, 1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 1);
My read function:
float Get_ADC(void){
float val;
float sensor_val;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 0); //pull down cs line on adc to enable spi on chip
t_buf[0] = 0b01000011;
t_buf[1] = 0b00010000;
//HAL_SPI_TransmitReceive(&hspi1, t_buf, r_buf, 3, 1000);
HAL_SPI_Transmit(&hspi1, t_buf, 1, 1000);
HAL_SPI_Receive(&hspi1, r_buf, 28, 1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, 1); //return cs line to high to disable spi on chip
return(sensor_val);
and the data i read:
r_buf[0] uint8_t 0 '\0'
r_buf[1] uint8_t 0 '\0'
r_buf[2] uint8_t 0 '\0'
r_buf[3] uint8_t 99 'c'
r_buf[4] uint8_t 28 '\034'
r_buf[5] uint8_t 171 '«'
r_buf[6] uint8_t 192 'À'
r_buf[7] uint8_t 48 '0'
r_buf[8] uint8_t 1 '\001'
r_buf[9] uint8_t 0 '\0'
r_buf[10] uint8_t 0 '\0'
r_buf[11] uint8_t 0 '\0'
r_buf[12] uint8_t 0 '\0'
r_buf[13] uint8_t 0 '\0'
r_buf[14] uint8_t 0 '\0'
r_buf[15] uint8_t 0 '\0'
r_buf[16] uint8_t 0 '\0'
r_buf[17] uint8_t 0 '\0'
r_buf[18] uint8_t 128 '\200'
r_buf[19] uint8_t 0 '\0'
r_buf[20] uint8_t 0 '\0'
r_buf[21] uint8_t 144 '\220'
r_buf[22] uint8_t 0 '\0'
r_buf[23] uint8_t 0 '\0'
r_buf[24] uint8_t 80 'P'
r_buf[25] uint8_t 165 '¥'
r_buf[26] uint8_t 0 '\0'
r_buf[27] uint8_t 12 '\f'
r_buf[28] uint8_t 0 '\0'
r_buf[3] returns the written config0 and .... ends with r_buf[28] the lock register.
r_buf[0],1,[2] should be returning my 24bit data and no matter what combination of config settings it will always return 0. I currently have a photometric diode attached to the ch0-ch1 respectivly. It is on a printed pcb attached to a stm32l412 chip with spi_mode(1,1).
My current assumption is that the adc never leaves shutdown/sleep mode and will not do any conversions.
-Ross
Upvotes: 0
Views: 2188
Reputation: 399
I had the same issue, also STM32 with HAL.
Turns out you have to either pull up IRQ line to DVDD or turn on internal pullup by setting IRQ[2] register bit to 1. This is briefly mentioned in datasheet section 3.4 as
When the IRQ pin is in High-Z mode, an external
pull-up resistor must be connected between DVDD and
the IRQ pin.
Upvotes: 1
Reputation: 391
It looks like you use STM32 HAL.
I found that after HAL_SPI_Transmit()
, I have to call HAL_SPIEx_FlushRxFifo(&hspi1);
before the next SPI operation. This is a quirk of the STM32 HAL. Alternatively, HAL_SPI_TransmitReceive()
works without the flush call.
Also, your call HAL_SPI_Transmit(&hspi1, t_buf, 1, 1000);
uses buffer size 1, but you previously initialized two bytes of t_buf
so I guess you want to send two bytes.
To separate if the ADC or the SPI is the problem, you can try to read the internal temperature of the ADC; by reading between channels MCP3564_REGISTER_MUX_VIN_PLUS_TEMP_P
and MCP3564_REGISTER_MUX_VIN_MINUS_TEMP_M
(and then convert according to datasheet section 5.1.2 and figure 2-32 or 2-33).
Upvotes: 0