Search code examples
stm32spi

STM32F103 CS5532 ADC SPI problem, cannot reset ADC


[SPI][1] [1]: https://i.sstatic.net/M6y8axtp.png

void CSlow(void){
    LL_GPIO_ResetOutputPin(GPIOA, NSS1_Pin);
}
void CShi(void){
    LL_GPIO_SetOutputPin(GPIOA, NSS1_Pin);
}
void SPI_Write32(uint32_t dat)
{
    int i;
    if((dat<<0)&0x80000000)       LL_GPIO_SetOutputPin(GPIOA, MOSI1_Pin);//CS5532_SDI=1;   
    else  LL_GPIO_ResetOutputPin(GPIOA, MOSI1_Pin);//CS5532_SDI=0;

    Delay(1);

    for(i=1;i<32;i++)
    {
        LL_GPIO_SetOutputPin(GPIOA, SCLK1_Pin);//CS5532_SCLK=1;    //时钟高
        Delay(1);

        if((dat<<i)&0x80000000)     LL_GPIO_SetOutputPin(GPIOA, MOSI1_Pin);//CS5532_SDI=1;  
        else  LL_GPIO_ResetOutputPin(GPIOA, MOSI1_Pin);//CS5532_SDI=0;

        LL_GPIO_ResetOutputPin(GPIOA, SCLK1_Pin);//CS5532_SCLK=0;    
        Delay(1);

    }
     LL_GPIO_SetOutputPin(GPIOA, SCLK1_Pin);//CS5532_SCLK=1;    
     Delay(1);
     LL_GPIO_ResetOutputPin(GPIOA, SCLK1_Pin);//CS5532_SCLK=0;    
     Delay(1);

//LL_GPIO_SetOutputPin(GPIOA, NSS1_Pin);//CS5532_CS = 1;
     Delay(1);

}
void SPI_Write(uint8_t dat)
{
    int i;
//  LL_GPIO_ResetOutputPin(GPIOA, NSS1_Pin);// CS5532_CS=0;

    if((dat<<0)&0x80)     LL_GPIO_SetOutputPin(GPIOA, MOSI1_Pin);//CS5532_SDI=1;   
    else  LL_GPIO_ResetOutputPin(GPIOA, MOSI1_Pin);//CS5532_SDI=0;

    Delay(1);

    for(i=1;i<8;i++)
    {
        LL_GPIO_SetOutputPin(GPIOA, SCLK1_Pin);//CS5532_SCLK=1;    
        Delay(1);

        if((dat<<i)&0x80)   LL_GPIO_SetOutputPin(GPIOA, MOSI1_Pin);//CS5532_SDI=1;   
        else  LL_GPIO_ResetOutputPin(GPIOA, MOSI1_Pin);//CS5532_SDI=0;

        LL_GPIO_ResetOutputPin(GPIOA, SCLK1_Pin);//CS5532_SCLK=0; 
        Delay(1);

}
    LL_GPIO_SetOutputPin(GPIOA, SCLK1_Pin);//CS5532_SCLK=1;   
    Delay(1);
    LL_GPIO_ResetOutputPin(GPIOA, SCLK1_Pin);//CS5532_SCLK=0;  
    Delay(1);

//LL_GPIO_SetOutputPin(GPIOA, NSS1_Pin);//CS5532_CS = 1;
    Delay(1);
}

uint32_t SPI_Read(uint8_t bitno)
{
    int i,j;
    uint32_t temp=0;

//CS5532_CS = 0;
    LL_GPIO_ResetOutputPin(GPIOA, NSS1_Pin);
    Delay(1);
    for(i = 0; i < bitno; i++)
    {
        LL_GPIO_SetOutputPin(GPIOA, SCLK1_Pin);//CS5532_SCLK = 1; 
        temp <<= 1;
        if(LL_GPIO_IsInputPinSet(GPIOA,MISO1_Pin))//(CS5532_SDO)
            temp |= 0x1;
        else
            temp &= 0xFFFFFFFE;
        Delay(1);
        LL_GPIO_ResetOutputPin(GPIOA, SCLK1_Pin);//CS5532_SCLK = 0;
        Delay(1);
    }
//CS5532_CS = 1;
    LL_GPIO_SetOutputPin(GPIOA, NSS1_Pin);
    Delay(1);
    return temp;
}
void ResetADC(void){
    uint32_t resetcommand = 0x1 << 29 , RVbit = 0x1 << 28,
    VRS = 0x1 << 25, resetbit =  0x0 ;
    uint8_t i,write = 0x3 , read = 0xB , value[4]={1,1,1,1};

    uint8_t resetsequence[16]=  {0xFF, 0xFF, 0xFF, 0xFF,
                         0xFF, 0xFF, 0xFF, 0xFF,
                         0xFF, 0xFF, 0xFF, 0xFF,
                         0xFF, 0xFF, 0xFF, 0xFE};

    for(i=0;i<16;i++){
        CSlow();
        SPI_Write(resetsequence[i]);
        CShi();
        Delay(1);
     }
    Delay(50);
    CSlow();

    SPI_Write(write);
    SPI_Write32(resetcommand);
    CShi();

    Delay(200);

    CSlow();
    SPI_Write(write);
    SPI_Write32(resetbit);
    CShi();

    while (1){
    ....
    CSlow();
    SPI_Write(0xa);
    CShi();
    receive=SPI_Read(32);

I use ADCreset for resetting comm port of CS5532 ADC from Cirrus and I read in the main {} gain register periodically

according to datasheet I must get 0x01000000 from ADC however I cant get any

the picture link below is logic analyser screenshot from periodical reading Apparently I cannot reset the ADC correctly can you please advice, thank you


Solution

  • I used 5V to power the CS5532 chip, the SCLK input of CS5532 does not sense the 3.3V clock pulses from STM32F103.

    It took me 1 month to understand the problem, even ChatGPT did not help me.

    When I supplied 3.3 V to CS5532 power input, the problem got solved. I must have read the datasheet of CS5532 better.