0
votes

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

2
I believe this hardware has a concept of register - value communication and you are breaking this by trying to write or read all at once. I suggest to look at datasheet how CS signal should control the communication.0andriy
It has an "incremental write or read" starting at the register specified and loops around until cs is high again. Also figure 1-1 Serial Output Timing Diagram, shows you write to slave address and what register you want to access to, and then read starting at the register 2 bits after the cs goes low. Device will send response after slave address is ack correct. I'm pretty new to spi communication but why would i get all the other correct register vales back just not the adc data?PowerOverSparks

2 Answers

0
votes

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).

0
votes

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.