2024-06-20 03:59 AM
Hello everybody,
I am somewhat new to the world of STM and still learning. I have written the code that reads the data over UART than it sends specific data "calculated" from the UARTS data to SPI then it reads back from SPI than it sends it to UART. The problem is when I send the data to the MCU (STM NUCLEO-F091RC board) the data is almost 85% of the time not received as it should. I have tried fetching the data with several programs. For know DockLight seems to be the best at doing it for the debuging. I am using interrupted receive and transmit for the UART so I dont need to wait the timeout. I am not using delays as I had incresed the Baud rate of the SPI and UART the frequency working frequency of the MCU is at 48 MHz. If you would need code I will post it after I clean up the comments in the code.
2024-06-20 05:08 PM
You're not going to get much help if you don't post your code. You haven't mentioned what kind of data you're sending to the F091? Variable data length, fixed data length? Bytes or strings?
2024-06-20 11:25 PM
I am sending fixed data length. Data type is byte ( uint8_t in hex format as spi devices only understand that).
And here is the code: and SPI at 1,5Mbits/s
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <String.h>
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
uint8_t Uartrec[3]; //Receive buffer for UART commands
uint8_t UartSend[6]; //Transmit buffer for UART
uint8_t Bankset[3]={0x40,0x0A,0x10}; //Premade command to setup ICON for all MCPs (0x40 is write command)
uint8_t SetportA[3]={0x40,0x00,0xFF}; //Premade command to make all pins of PORTA as inputs
uint8_t SetportB[3]={0x40,0x01,0xFF}; //Premade command to make all pins of PORTB as inputs
uint8_t PortAPull[3]={0x40,0x0c,0xFF}; //Premade command to setup pullup resistors of high impedance for PORTA
uint8_t PortBpull[3]={0x40,0x0d,0Xff}; //Premade command to setup pullup resistors of high impedance for PORTB
uint8_t SpiSend[3]; //Transmit buffer for SPI, 2nd and 3d snippet determinated by MCU 1st snippet is copied from UARTrec[0]
uint8_t ReadA[2]={0x41,0x12}; //Premade command to read PORTA status (0x41 lets the MCP to know which PORT to read in this case 0x12 is PORTA and 0x13 is PORTB)
uint8_t ReadB[2]={0x41,0x13}; //Premade command to read PORTB status
int size;
uint8_t SendDS=0;
uint8_t Tready=0;
uint8_t Good[1];
struct commands
{
uint8_t ReadA[2];
uint8_t ReadB[2];
uint8_t PortBpull[3];
uint8_t PortAPull[3];
uint8_t SetportA[3];
uint8_t SetportB[3];
}CMD;
struct exp
{
struct commands cmd;
uint8_t ReadA[2];
uint8_t ReadB[2];
GPIO_TypeDef* port;
uint16_t pinmask;
uint8_t Arec[1];
uint8_t Brec[1];
} MCPS[2];
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
void ReadMCPs(struct exp MCP[],int i, uint8_t M[]);
void InitMCPs(struct exp MCP[],int i);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI1_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
//SpiSend = 0x40 is set to write
//UartSend 0 and 3 are indicator of "serial number of MCP"
Good[0]=0xAB;
SpiSend[0]=0x40;
UartSend[0]=0x01;
UartSend[3]=0x02;
memcpy(CMD.ReadA,ReadA,sizeof(ReadA));
memcpy(CMD.ReadB,ReadB,sizeof(ReadB));
memcpy(CMD.SetportA,SetportA,sizeof(SetportA));
memcpy(CMD.SetportB,SetportB,sizeof(SetportB));
memcpy(CMD.PortAPull,PortAPull,sizeof(PortAPull));
memcpy(CMD.PortBpull,PortBpull,sizeof(PortBpull));
MCPS[0].port=CS_GPIO_Port;
MCPS[0].pinmask=CS_Pin;
MCPS[1].port=CS2_GPIO_Port;
MCPS[1].pinmask=CS2_Pin;
MCPS[0].cmd=CMD;
MCPS[1].cmd=CMD;
size=sizeof(MCPS)/sizeof(MCPS[0]);
//ICON Bank=0 Mirror=0, Sequential operation=0, Slew Rate=1 (Disabled, 0 only if MCP23017 is used), Hardware addressing=0, Interrupt open drain =0, Interrupt polarity=0
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, Bankset, 3);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, Bankset, 3);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_SET);
InitMCPs(MCPS, size);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
//Receive commands for MCPs via UART
HAL_UART_Receive_IT(&huart1, Uartrec, 3);
//Nested switch/case statement for active/running setup of pins and ports
//Sets up single pin or multiple pins of MCPs as output and sets it low
//Other pins are setup as inputs with high impedance pullup resistor
//variable to use for switch case is first snipet of UART command, it is "serial number of MCP"
switch(Uartrec[0])
{
case 0x01:
{
switch(Uartrec[1])
{
case 0x01:
{
//Setup outputs of port A
SpiSend[1]=0x00;
SpiSend[2]=0xFF-Uartrec[2];
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SpiSend, 3);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
//Setup pullup resistor register of PORTA
SpiSend[1]=0x0C;
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SpiSend, 3);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
//Set output register of PORTA
SpiSend[1]=0x14;
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SpiSend, 3);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
break;
}
case 0x02:
{
//Setup outputs of PORTB
SpiSend[1]=0x01;
SpiSend[2]=0xFF-Uartrec[2];
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SpiSend, 3);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
//Setup pullup resistor register of PORTB
SpiSend[1]=0x0D;
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SpiSend, 3);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
//Set output register of PORTB
SpiSend[1]=0x15;
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SpiSend, 3);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
break;
}
}
Uartrec[0]=0x00;
Uartrec[1]=0x00;
Uartrec[2]=0x00;
break;
}
case 0x02:
{
switch(Uartrec[1])
{
case 0x01:
{
SpiSend[1]=0x00;
SpiSend[2]=0xFF-Uartrec[2];
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SpiSend, 3);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_SET);
SpiSend[1]=0x0C;
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SpiSend, 3);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_SET);
SpiSend[1]=0x14;
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SpiSend, 3);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_SET);
break;
}
case 0x02:
{
SpiSend[1]=0x01;
SpiSend[2]=0xFF-Uartrec[2];
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SpiSend, 3);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_SET);
SpiSend[1]=0x0D;
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SpiSend, 3);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_SET);
SpiSend[1]=0x15;
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SpiSend, 3);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_SET);
break;
}
}
Uartrec[0]=0x00;
Uartrec[1]=0x00;
Uartrec[2]=0x00;
break;
}
//This case for out switch/case should set all pins as inputs with high impedance pullup resistor
//This would represent none testing state/phase
case 0xFF:
{
//setup of MCPs pins and ports as input with high impedance pullup resistors
//It is same as initial setup (It would be best to make independent function out of it to make the code lighter)
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SetportA, 3);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, PortAPull, 3);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SetportB, 3);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, PortBpull, 3);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SetportA, 3);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, PortAPull, 3);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SetportB, 3);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, PortBpull, 3);
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_SET);
Uartrec[0]=0x00;
Uartrec[1]=0x00;
Uartrec[2]=0x00;
break;
}
case 0XEE: //Put up SendDS flag to 1 so the MCU can send data back to pc
{
SendDS=1;
//HAL_UART_Transmit_IT(&huart1, Good, 1);
//HAL_Delay(50);
Uartrec[0]=0x00;
Uartrec[1]=0x00;
Uartrec[2]=0x00;
break;
}
case 0XEF: //Put down SendDS flag so the MCU stops sending data back to the pc
{
SendDS=0;
Uartrec[0]=0x00;
Uartrec[1]=0x00;
Uartrec[2]=0x00;
break;
}
default:
{
Uartrec[0]=0x00;
Uartrec[1]=0x00;
Uartrec[2]=0x00;
break;
}
}
ReadMCPs(MCPS, size, UartSend);
if(SendDS==1)
{
HAL_UART_Receive_IT(&huart1, Uartrec, 3);
HAL_UART_Transmit_IT(&huart1, UartSend, 6);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief SPI1 Initialization Function
* @PAram None
* @retval None
*/
static void MX_SPI1_Init(void)
{
/* USER CODE BEGIN SPI1_Init 0 */
/* USER CODE END SPI1_Init 0 */
/* USER CODE BEGIN SPI1_Init 1 */
/* USER CODE END SPI1_Init 1 */
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI1_Init 2 */
/* USER CODE END SPI1_Init 2 */
}
/**
* @brief USART1 Initialization Function
* @PAram None
* @retval None
*/
static void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 38400;
huart1.Init.WordLength = UART_WORDLENGTH_9B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_EVEN;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @PAram None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : CS2_Pin */
GPIO_InitStruct.Pin = CS2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(CS2_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : CS_Pin */
GPIO_InitStruct.Pin = CS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(CS_GPIO_Port, &GPIO_InitStruct);
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
HAL_UART_Receive_IT(&huart1, Uartrec, 3);
}
//Function for reading status of Ports of the MCPs
void ReadMCPs(struct exp MCP[],int i, uint8_t M[])
{
int x=0;
for(int j=0;j<i;j++)
{
HAL_GPIO_WritePin(MCP[j].port, MCP[j].pinmask, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, MCPS[j].cmd.ReadA, 2);
HAL_SPI_Receive_IT(&hspi1, MCP[j].Arec, 1);
HAL_GPIO_WritePin(MCP[j].port, MCP[j].pinmask, GPIO_PIN_SET);
HAL_GPIO_WritePin(MCP[j].port, MCP[j].pinmask, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, ReadB, 2);
HAL_SPI_Receive_IT(&hspi1, MCP[j].Brec, 1);
HAL_GPIO_WritePin(MCP[j].port, MCP[j].pinmask, GPIO_PIN_SET);
M[x+1]=MCP[j].Arec[0];
M[x+2]=MCP[j].Brec[0];
x=x+3;
}
}
//Function for Initialization and reseting (reinitialization while testing) of the MCPs
//Will be upgraded to also setup the ICON bank
void InitMCPs(struct exp MCP[],int i)
{
for(int j=0;j<i;j++)
{
HAL_GPIO_WritePin(MCP[j].port, MCP[j].pinmask, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SetportA, 3);
HAL_GPIO_WritePin(MCP[j].port, MCP[j].pinmask, GPIO_PIN_SET);
HAL_GPIO_WritePin(MCP[j].port, MCP[j].pinmask, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, PortAPull, 3);
HAL_GPIO_WritePin(MCP[j].port, MCP[j].pinmask, GPIO_PIN_SET);
HAL_GPIO_WritePin(MCP[j].port, MCP[j].pinmask, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, SetportB, 3);
HAL_GPIO_WritePin(MCP[j].port, MCP[j].pinmask, GPIO_PIN_SET);
HAL_GPIO_WritePin(MCP[j].port, MCP[j].pinmask, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi1, PortBpull, 3);
HAL_GPIO_WritePin(MCP[j].port, MCP[j].pinmask, GPIO_PIN_SET);
}
}
void MCPcontrol(struct exp MCP[], int i,uint8_t MSG[])
{
//switch(MSG[0]):
}
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @PAram file: pointer to the source file name
* @PAram line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
2024-06-21 12:20 AM
Are you not having issues with UART reception? There was nothing in your OP mentioning SPI issues.
You're not using HAL_UART_Receive_IT correctly. You don't use it inside a while loop. You need it once before the while loop just to init the interrupt. Then call HAL_UART_Receive_IT inside HAL_UART_RxCpltCallback.
But you need to set a flag indicating you have received something inside of HAL_UART_RxCpltCallback. Then check the flag in your while loop. Then you can check for your array data.
See this project which receives 10 bytes with a checksum. It also uses HAL_UARTEx_ReceiveToIdle_IT which will look for idle time. It uses a ring buffer to received multiple messages in a queue. cnt_Handle is the flag to indicate there is a new packet. So if the message received valid data it'll transmit it back. If not valid like if you received only 9 bytes and it idles, it'll ignore the packet and do nothing. That way your next packet will be in sync.
https://github.com/karlyamashita/ParseTelemetryData
2024-06-21 12:25 AM
Sorry for not making it clear. I have no issue with SPI communication just with UART. I will try the solution you mentioned.
2024-06-26 12:47 AM
Sorry for the long wait. I have tried implementing your example in my code. For me it does not work. Maybe I need to create new project and copy everything to it. Anyways I have took your advice to remove and use HAL_UART_Receive_IT outside while loop and main function. I was thinking that maybe just maybe after I send the data from my PC application ISR for HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) lands in the part of the code where I flush the my UART input buffer (Uartrec variable). Would it be better to remove that part and flush the UART input buffer generated by STM32CubeIDE. I am also thinking about a jump to start of the while loop after HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) has been called. This way I could be sure that my program would not send back nonsense and try to infinitely send calculated data to SPI.