2022-02-11 11:27 AM
I have no idea why this code is not working. I am sending chunks of a file with UART followed by short instructions of 2 bytes to tell the MCU whether another chunk is coming or to start playing the file.
The MCU receives the first chunk without an issue, but gets stuck on HAL_UART_Receive_IT (&huart2, inst, 2). After this instruction, the MCU does not react to anything coming from the computer via UART. What am I doing wrong?
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_USART2_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
GPIOC->ODR =0;
uint8_t buffer_in0 [BUFFER_SZ] = {0};
uint8_t buffer_in1 [BUFFER_SZ] = {0};
uint8_t buffer_in2 [BUFFER_SZ] = {0};
uint8_t buffer_in3 [BUFFER_SZ] = {0};
uint8_t buffer_in4 [BUFFER_SZ] = {0};
uint8_t buffer_in5 [BUFFER_SZ] = {0};
uint8_t buffer_in6 [BUFFER_SZ] = {0};
uint8_t *buffer_in [7];
buffer_in[0] = buffer_in0;
buffer_in[1] = buffer_in1;
buffer_in[2] = buffer_in2;
buffer_in[3] = buffer_in3;
buffer_in[4] = buffer_in4;
buffer_in[5] = buffer_in5;
buffer_in[6] = buffer_in6;
uint8_t data_out[4] = {0};
uint16_t* msg_pointer = (uint16_t*) data_out;
*msg_pointer = STOP;
uint8_t num_of_chunks = 0;
uint32_t c = 0;
uint8_t inst [2] = {0};
uint16_t* inst_point = (uint16_t*) inst;
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
uint8_t* data_in = buffer_in [num_of_chunks];
uint16_t* magic_number_pointer =(uint16_t*) data_in;
uint32_t* checksum_pointer = (uint32_t*) (data_in +2);
uint16_t* len_pointer = (uint16_t*) (data_in + 6);
HAL_UART_Receive_IT (&huart2, data_in, BUFFER_SZ);
while (*magic_number_pointer != magic_number) {
__NOP();
}
c= chksm (data_in+8,*len_pointer);
uint8_t correct = c == *checksum_pointer;
if (correct)
{
*msg_pointer = OK;
HAL_UART_Transmit (&huart2, data_out, sizeof (data_out), 2);
num_of_chunks++;
HAL_UART_Receive_IT (&huart2, inst, 2);
while (*inst_point != START && *inst_point != NEXT) {
__NOP();
}
*msg_pointer = *inst_point;
HAL_UART_Transmit (&huart2, data_out, sizeof (data_out), 2);
if (*inst_point == START) {
play_all(buffer_in, num_of_chunks);
num_of_chunks = 0;
data_in = buffer_in[0];
data_in [0] = 0 ; //override magic number;
data_in [1] = 0 ;
*msg_pointer = STOP; // finish
HAL_UART_Transmit (&huart2, data_out, sizeof (data_out), 2);
}
*inst_point = 0;
}
else
{
*msg_pointer = chksmErr;
HAL_UART_Transmit (&huart2, data_out, sizeof (data_out), 2);
}
}
/* USER CODE END 3 */
}
2022-02-11 12:01 PM
The logic here is pretty complicated. Monitor the return value from HAL functions. You may be trying to restart a RX before the last has finished. And/or pause the program when it's "stuck" and verify the values in the UART handle are as expected.
2022-02-11 01:26 PM
I tried checking the return values for the UART transfer and only continue if its 0. It seems to solve the first issue, but when I continue with the second chunk, even though the return value is 0, it still doesn't react to any incoming data
busy = 2;
while (busy != 0)
busy = HAL_UART_Receive_IT (&huart2, data_in, BUFFER_SZ);
2022-02-11 01:31 PM
I tried checking the return values for the UART transfer and only continue if its 0. It seems to solve the first issue, but when I continue with the second chunk, even though the return value is 0, it still doesn't react to any incoming data
busy = 2;
while (busy != 0)
busy = HAL_UART_Receive_IT (&huart2, data_in, BUFFER_SZ);
2022-02-11 01:43 PM
Check for the overrun error flags in the USART_SR register.
2022-02-11 02:20 PM
Its set to 1 when I get it, but what does it mean?
2022-02-11 03:14 PM
2022-02-11 04:15 PM
I did something. I have absolutely no idea what, but for some reason it works now.
I wish I could tell what that was so that other people can learn from it, but I guess it's like that sometimes
2022-02-12 12:33 AM
Primary fail is
while (*magic_number_pointer != magic_number) {
__NOP();
}
you dont handle no magic received...
2022-02-12 01:41 AM
yes you can use as a double buffer.
The double buffer can be thought of as two completely separate units where the interrupt routine works with one unit and the program works with another unit. For the sake of modeling, the interrupt routine will be referred to as the “Kernel�? and functions + programs that do not make up the interrupt routine will be referred to as the “User�? (they use the data, the Kernel handles the hardware).