cancel
Showing results for 
Search instead for 
Did you mean: 

HAL drivers SPI problem on STM32F4 Discovery

cesar
Associate
Posted on February 16, 2016 at 17:32

I have run into a problem when trying to setup a SPI com between the STM32F4 Discovery and a CR95HF RFID. The MISO data looks correct in the scope, however the software reads the bit 0 as 0 always, giving me the wrong data. this is the code.

This is my SPI and GPIO inits:


#define CR95HF_SPI SPI1
#define CR95HF_SPI_ALT GPIO_AF5_SPI1

#define CR95HF_SPI_SCK_PIN GPIO_PIN_3 
#define CR95HF_SPI_SCK_GPIO_PORT GPIOB
 
#define CR95HF_SPI_MISO_PIN GPIO_PIN_4 
#define CR95HF_SPI_MISO_GPIO_PORT GPIOB 
 
#define CR95HF_SPI_MOSI_PIN GPIO_PIN_5 
#define CR95HF_SPI_MOSI_GPIO_PORT GPIOB 
 
#define CR95HF_SPI_NSS_PIN GPIO_PIN_7 
#define CR95HF_SPI_NSS_GPIO_PORT GPIOD
 
 
GPIO_InitTypeDef GPIO_InitStruct;
//SCK
GPIO_InitStruct.Pin = CR95HF_SPI_SCK_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Alternate = CR95HF_SPI_ALT;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(CR95HF_SPI_SCK_GPIO_PORT, &GPIO_InitStruct); 
//MISO
GPIO_InitStruct.Pin = CR95HF_SPI_MISO_PIN ;
HAL_GPIO_Init(CR95HF_SPI_MISO_GPIO_PORT, &GPIO_InitStruct); 
//MOSI
GPIO_InitStruct.Pin = CR95HF_SPI_MOSI_PIN;
HAL_GPIO_Init(CR95HF_SPI_MOSI_GPIO_PORT, &GPIO_InitStruct); 
//SS A.K.A CS
HAL_GPIO_WritePin(CR95HF_SPI_NSS_GPIO_PORT, CR95HF_SPI_NSS_PIN, GPIO_PIN_SET); 
GPIO_InitStruct.Pin = CR95HF_SPI_NSS_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(CR95HF_SPI_NSS_GPIO_PORT, &GPIO_InitStruct);

SPI_InitTypeDef SPI_InitStructure;
//Setup SPI 
hspi.Instance = CR95HF_SPI;
hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
hspi.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi.Init.Direction = SPI_DIRECTION_2LINES;
hspi.Init.Mode = SPI_MODE_MASTER;
hspi.Init.DataSize = SPI_DATASIZE_8BIT;
hspi.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi.Init.CRCPolynomial = 7;
hspi.Init.TIMode = SPI_TIMODE_DISABLE;
hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi.Init.NSS = SPI_NSS_SOFT;
//#ifdef USE_DMA
//SPI_I2S_DMACmd(CR95HF_SPI, SPI_I2S_DMAReq_Rx, ENABLE);
//SPI_I2S_DMACmd(CR95HF_SPI, SPI_I2S_DMAReq_Tx, ENABLE);
//#endif 
if (HAL_SPI_Init(&hspi) != HAL_OK)
{
return 1;
}
return 0;

This is the functions I use to receive data

CR89HF_SPI_NSS_set(); 
SPI_txByte(CR95HF_COMMAND_RECEIVE); 
pResponse[0] = SPI_rxByte(); // read response code
pResponse[1] = SPI_rxByte(); // read data length
for (i = 0; i < pResponse[1]; i++)
{
pResponse[i + 2] = SPI_rxByte();
}
CR89HF_SPI_NSS_reset();
void SPI_txByte(uint8_t data)
{ 
taskENTER_CRITICAL();
switch (HAL_SPI_Transmit(&hspi, &data, 1, 100)) {
case HAL_OK: 
break;
case HAL_BUSY:
//debug(''PANIC: SPI: busy state occured at %s, line %d .\n'', __FILE__, __LINE__);
while (1)
;
break;
case HAL_TIMEOUT:
//debug(''PANIC: SPI: transmit/receive timeout occured at %s, line %d .\n'', __FILE__, __LINE__);
while (1)
;
break; 
case HAL_ERROR:
//debug(''PANIC: SPI: transmit/receive error at %s, line %d.\n'', __FILE__, __LINE__);
while (1)
;
break;
default:
//debug(''PANIC: SPI: transmit/receive WUT HAPPEND at %s, line %d.\n'', __FILE__, __LINE__);
while (1)
;
break;
}
taskEXIT_CRITICAL();
}
/**
* @brief Receives one byte over SPI
* @retval None 
*/
uint8_t SPI_rxByte()
{
uint8_t recv_data;
taskENTER_CRITICAL();
switch (HAL_SPI_Receive(&hspi, &recv_data, 1, 100)) {
case HAL_OK: 
break;
case HAL_BUSY:
//debug(''PANIC: SPI: busy state occured at %s, line %d .\n'', __FILE__, __LINE__);
while (1)
;
break;
case HAL_TIMEOUT:
//debug(''PANIC: SPI: transmit/receive timeout occured at %s, line %d .\n'', __FILE__, __LINE__);
while (1)
;
break; 
case HAL_ERROR:
//debug(''PANIC: SPI: transmit/receive error at %s, line %d.\n'', __FILE__, __LINE__);
while (1)
;
break;
default:
//debug(''PANIC: SPI: transmit/receive WUT HAPPEND at %s, line %d.\n'', __FILE__, __LINE__);
while (1)
;
break;
}
taskEXIT_CRITICAL();
return recv_data;
}

This is what I see on the Scope:

http://imgur.com/a/5jpky

So, basically what I see on the scope looks fine, but the software instead of returning the MISO data, is reading the ''garbage'' bytes being sent to read data. I.e. I am expecting to read 4E 46 43 20 .... but what the software reads is 4F 46 42 20, bit 0 is always read as 0. Can somebody guide me on how to solve this? something i might be doing wrong? Thanks
2 REPLIES 2
cesar
Associate
Posted on February 17, 2016 at 23:01

I solved the problem slowing down the clock, running at 150 kHz seems to work fine. My application is not time critical so i am OK with that, but the CR95HF is supposed to work with an SPI CLK of up to 2 MHz, I tried with as low as 500KHz and it would work.

mark239955_stm1
Associate II
Posted on February 18, 2016 at 12:27

Try configuring the SCK and MOSI pins for higher speeds, at least medium and maybe fast.