SPI Rx buffer not reading
Hello,
I am trying to get my MCP3204 ADC to run with my STM32F4. Unfortunately all I get from my SPI_I2S_ReceiveData() function is a bunch of zeros. According to my oscilloscope everything looks normal. I am getting a clock signal, a MOSI transmission to the ADC that looks normal and is in the right range, the chip select signal looks fine and the ADC is answering with what looks like a word that reacts accurately to potentiometer movement. But my STM32F4 just won’t read anything from the SPI4->DR register.
I also tried a simple loopback test connecting MISO and MOSI. The result is the same. All signals look normal on my scope, all the flags are set and cleared, all clocks are running but the SPI read register still appears empty. I also tried the same on SPI2 with the same negative result.
Also I can assure that the problem is not with the <*pitchP>pointer or anything down stream, since it works just fine if I replace <value> with any constant integer value.
Unfortunately I don’t have a multi channel scope or logic analyzer to look at the timing at the pins but the code for the send/receive procedure I am using is very basic and by the book and it works in countless other projects.
Any help is much appreciated!
void init_Clocks(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2, ENABLE); // maybe try DMA for ADC at some point
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_SPI4 | RCC_APB2Periph_ADC1, ENABLE); // SPI1 Clock - DAC, SPI4 Clock - ADC, ADC1 Clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // TIM2 Timer - Clock prescale 2
}
void init_ADC_ext (void)
{
// Initialize CS pin.
GPIO_InitTypeDef gpio_init;
gpio_init.GPIO_Pin = GPIO_Pin_12;
gpio_init.GPIO_Speed = GPIO_Fast_Speed;
gpio_init.GPIO_Mode = GPIO_Mode_OUT;
gpio_init.GPIO_OType = GPIO_OType_PP;
gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &gpio_init);
// Initialize CLK pin.
gpio_init.GPIO_Pin = GPIO_Pin_13;
gpio_init.GPIO_Speed = GPIO_Fast_Speed;
gpio_init.GPIO_Mode = GPIO_Mode_AF;
gpio_init.GPIO_OType = GPIO_OType_PP;
gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &gpio_init);
// Initialize MOSI pin.
gpio_init.GPIO_Pin = GPIO_Pin_1;
gpio_init.GPIO_Speed = GPIO_Fast_Speed;
gpio_init.GPIO_Mode = GPIO_Mode_AF;
gpio_init.GPIO_OType = GPIO_OType_PP;
gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &gpio_init);
// Initialize MISO pin. This one is not receiving anything.
gpio_init.GPIO_Pin = GPIO_Pin_11;
gpio_init.GPIO_Speed = GPIO_Fast_Speed;
gpio_init.GPIO_Mode = GPIO_Mode_IN; // MISO must be configured as HI-Z IN, not AF!!
// gpio_init.GPIO_OType = GPIO_OType_PP;
gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &gpio_init);
// Initialize SPI
SPI_InitTypeDef spi_init;
spi_init.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
spi_init.SPI_Mode = SPI_Mode_Master;
spi_init.SPI_DataSize = SPI_DataSize_16b; // SPI_DataSize_8b for ADCread()
spi_init.SPI_CPOL = SPI_CPOL_Low;
spi_init.SPI_CPHA = SPI_CPHA_1Edge;
spi_init.SPI_NSS = SPI_NSS_Soft;
spi_init.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // Prescaler_64 for ADCread()
spi_init.SPI_FirstBit = SPI_FirstBit_MSB;
spi_init.SPI_CRCPolynomial = 7;
SPI_Init(SPI4, &spi_init);
// GPIO_SetBits(GPIOB, GPIO_Pin_12);
SPI_Cmd(SPI4, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_SPI4);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_SPI4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF6_SPI4);
}
void loopback(void){
uint16_t value = 0;
while (SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI4, 440);
while (SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_RXNE) == RESET);
value = SPI_I2S_ReceiveData(SPI4);
*pitchP = value;
}
void ADCread(void){
uint16_t value = 0;
GPIO_ResetBits(GPIOB, GPIO_Pin_12);
// Send header
while (SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI4, 0b00000110); // or 0x04 | 0x02
while (SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_RXNE) == RESET);
SPI_I2S_ReceiveData(SPI4);
// Send channel / receive first part
while (SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI4, 0b00000000); // 0b01000000 for the other channel
while (SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_RXNE) == RESET);
value = (SPI_I2S_ReceiveData(SPI4) & 0xf) << 8;
// Send trailing word / receive second part
while (SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI4, 0x00);
while (SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_RXNE) == RESET);
value |= SPI_I2S_ReceiveData(SPI4);
GPIO_SetBits(GPIOB, GPIO_Pin_12);
*pitchP = value;
}
int main (){
SystemInit();
init_Clocks();
init_ADC_ext();
while(1) {
Loopback();
ADCread();
}
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?