2018-08-15 11:46 AM
Hello,
I am working on a code that uses the HAL library for SPI communication. But I have a problem with SPI's state-checking routine.
void libera_escrita(void)
{
SPI_TxBuffer[0] = 6;
HAL_GPIO_WritePin(GPIOC, CS_Pin, GPIO_PIN_RESET);
while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
HAL_SPI_TransmitReceive_IT(&hspi1, (uint8_t*)SPI_TxBuffer, (uint8_t *)SPI_RxBuffer, 1);
while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
HAL_GPIO_WritePin(GPIOC, CS_Pin, GPIO_PIN_SET);
}
My code stays in that while, what could be causing this?
2018-08-15 01:39 PM
You shouldn't be using the HAL_SPI_TransmitReceive_IT(),
I dont bother to DMA the SPI since I am not streaming data like Audio
I use these routines without issue:
void transfer(unsigned short data) {
char RxSPI;
while (!(hspi1.Instance->SR & SPI_FLAG_TXE)) ; // wait while not empty
*((__IO uint8_t *)&hspi1.Instance->DR) = data; // send datat here
RxSPI = hspi1.Instance->DR;// + readSPI_SR; // read Rx byte and discard, only clearing the buffer
}
char transfer_receive(unsigned short data) {
char RxSPI;
while(!(hspi1.Instance->SR & SPI_FLAG_TXE))
;
while ((hspi1.Instance->SR & SPI_FLAG_RXNE)) // load all the bytes received, only keep the last one
RxSPI = hspi1.Instance->DR; //empty fifo
*((__IO uint8_t *)&hspi1.Instance->DR) = data; // force the SPI to transceive 8 bit
while(!(hspi1.Instance->SR & SPI_FLAG_TXE)) // wait to transmitter double buffer to shift into transmitter
;
while ((hspi1.Instance->SR & SPI_FLAG_BSY)) ; // wait for data to shift out of the processor pins
while((hspi1.Instance->SR & SPI_FLAG_RXNE)) // load all the bytes received, only keep the last one
RxSPI = hspi1.Instance->DR; // we only want the last byte
return RxSPI;
}
like this:
void eraseSector(char command, uint32_t address){
enableFlashWrites();
// command should be BlockErase4k, or BlockErase12k or ChipErase
HAL_GPIO_WritePin(AT25DN256_nSS_GPIO_Port, AT25DN256_nSS_Pin, GPIO_PIN_RESET);
transfer(command);
char addressByte2 = (address >> 16) & 0xff;
char addressByte1 = (address >> 8) & 0xff;
char addressByte0 = (address) & 0xff;
char dummyByte = 0;
transfer(addressByte2);
transfer(addressByte1);
transfer_receive(addressByte0);
HAL_GPIO_WritePin(AT25DN256_nSS_GPIO_Port, AT25DN256_nSS_Pin, GPIO_PIN_SET);
// erase should start now
}
and something a little more detailed :
void readFlashBytes(uint32_t address, int length, char*ptr){
int flashStatus1 = readFlashCommand(ReadStatusByte);
int flashStatus2 = readFlashCommand(ReadStatusByte2);
// printf(string, "Flash Status bytes %02x", flashStatus1);
while((flashStatus1 & 0x01)) {
// busy not ready
checkBackgroundServices(); // this checks the Uart DMAs progress " OS services"
flashStatus1 = readFlashCommand(ReadStatusByte);
}
HAL_GPIO_WritePin(AT25DN256_nSS_GPIO_Port, AT25DN256_nSS_Pin, GPIO_PIN_RESET);
transfer(ReadFlashByte);
char addressByte2 = (address >> 16) & 0xff;
char addressByte1 = (address >> 8) & 0xff;
char addressByte0 = (address) & 0xff;
char dummyByte = 0;
transfer(addressByte2);
transfer(addressByte1);
transfer(addressByte0);
while (length--)
{
*ptr = transfer_receive(dummyByte);
ptr++;
}
HAL_GPIO_WritePin(AT25DN256_nSS_GPIO_Port, AT25DN256_nSS_Pin, GPIO_PIN_SET);
}
2018-08-16 09:35 AM
Hello thank you for the answer
I used the routine you suggested, but it seems I still have the same problem. When executing the following line
while (! (hspi1.Instance-> SR & SPI_FLAG_TXE));
The code is locked on this line.
2018-08-16 11:10 AM
Are you sure you have the relevant clocks running? Have a look at the SPI examples in CubeMX
2018-08-16 03:38 PM
I use this to initialise ...
void CAN_Config() {
CAN_FilterConfTypeDef sFilterConfig;
static CanTxMsgTypeDef TxMessage;
static CanRxMsgTypeDef RxMessage;
//##-1- Configure the CAN peripheral #######################################
hcan.pTxMsg = &TxMessage;
hcan.pRxMsg = &RxMessage;
hcan.pTxMsg->RTR = CAN_RTR_DATA;
hcan.pTxMsg->DLC = 8;
hcan.pTxMsg->StdId = 0x101;
hcan.pTxMsg->ExtId = 0x102;
hcan.pRxMsg->DLC = 8;
hcan.pRxMsg->StdId = 0x101;
hcan.pRxMsg->ExtId = 0x102;
hcan.pRxMsg->RTR = CAN_RTR_DATA;
if(HAL_CAN_Init(&hcan) != HAL_OK)
{
// Initiliazation Error
_Error_Handler(__FILE__, __LINE__);
}
//##-2- Configure the CAN Filter ###########################################
sFilterConfig.FilterNumber = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x400 << 5; //11-bit ID in top bits
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x600 << 5; // resolves as 0x0400 - 0x05FF
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = 0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.BankNumber = 0;
if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
// Filter configuration Error
_Error_Handler(__FILE__, __LINE__);
char string[38];
sprintf( string, "Can Filter configuration Error\n\r");
puts1( string);
}
//##-2- Configure the 2nd CAN Filter ###########################################
sFilterConfig.FilterNumber = 1;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x600 << 5; //11-bit ID in top bits // command channel
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x700 << 5; // resolves as 0x0600 - 0x06FF
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = 1;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.BankNumber = 1;
if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
// Filter configuration Error
_Error_Handler(__FILE__, __LINE__);
char string[38];
sprintf( string, "Can Filter configuration Error\n\r");
puts1( string);
}
}
thats wrapped in my own CanStartup routine.
void initCairoCan(void) {
CAN_Config();
canRxpointerIN = 0;
canRxMsgIN = 0;
canRxMsgOUT = 0;
canRxMsgTableEMPTY = true;
canRxMsgTableFULL = false;
for (int i = 0; i < 16; i++)
IOCanMsgFlag[i] = false;
__HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP1);
__HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP0);
canTxMsgIN = 0;
canTxMsgOUT = 0;
canTxMsgTableEMPTY = true;
canTxMsgTableFULL = false;
canTxMsgTableOverflow = false;
canTxMsgOverrun = false;
blockCanTx = false;
}
then it all works.
2018-08-17 05:12 AM
TJ, Is this routine that you sent is not for CAN protocol?
2018-08-17 03:19 PM
my bad, wrong post... :)
2018-08-22 05:42 AM
Hello, I still have the same problem. My code stops executing because the status of the SPI bus stays as:
HAL_SPI_STATE_BUSY_TX_RX = 0x05U, / *! <Data Transmission and Reception process is ongoing * /
Would anyone have any more suggestions?
2018-08-22 10:25 AM
I have now realized that the SPI problem is only caught after some data has been received by the UART
2018-08-22 03:23 PM
Did you find the issue ?