2025-05-02 5:50 AM - edited 2025-05-02 7:59 AM
Hi, I've been trying to receive 5 bytes of data from a master MCU using SPI in slave mode.
I have a timeslot control signal, and on each falling edge of that signal, I need to receive 5 bytes from the master.
The timeslot control signal consists of one long pulse followed by 15 short pulses.
Exemple: i receive the data for timeslot 0 at the end of timeslot 15 and so on.
I want to start receiving data from the second cycle of the timeslot control signal, and stop at the end of that cycle,
so I can compare the received data with what I’m supposed to get.
the yellow signal is my timeslot control and the green is the duration of the HAL_TIM_PWM_PulseFinishedCallback
here is my code:
#define RX_BUFFER_SIZE 5
#define number_of_timeslot 16
uint8_t rx_all_data[number_of_timeslot][RX_BUFFER_SIZE];
volatile uint8_t reading_in_progress = 0;
volatile uint8_t g_index_ts = 1;
volatile uint8_t g_ready_to_listen = 0;
volatile uint8_t g_current_ts_index = 0;
volatile uint8_t g_current_cycle = 0;
volatile uint8_t read_data_finished = 0;
volatile int is_timeslots_readed[16] = {0};
uint16_t NumberOfTS_Cycles_to_Run = 2;// set to 0 for freerun.
g_TSC_Max_TimeSlotsToRun = 16;
g_TSC_Phases_To_Run = NumberOfTS_Cycles_to_Run!=0 ? 2*NumberOfTS_Cycles_to_Run : -1;
uint8_t g_expected_data[number_of_timeslot][RX_BUFFER_SIZE] = {
{0x35, 0x80, 0x00, 0x80, 0x00}, // TS0
{0x35, 0x00, 0x80, 0x80, 0x00}, // TS1
{0x35, 0x90, 0x10, 0x90, 0x10}, // TS2
{0x35, 0x10, 0x90, 0x10, 0x90}, // TS3
{0x35, 0xA0, 0x20, 0xA0, 0x20}, // TS4
{0x35, 0x20, 0xA0, 0x20, 0xA0}, // TS5
{0x35, 0xB0, 0x30, 0xB0, 0x30}, // TS6
{0x35, 0x30, 0xB0, 0x30, 0xB0}, // TS7
{0x35, 0xC0, 0x40, 0xC0, 0x40}, // TS8
{0x35, 0x40, 0xC0, 0x40, 0xC0}, // TS9
{0x35, 0xD0, 0x50, 0xD0, 0x50}, // TS10
{0x35, 0x50, 0xD0, 0x50, 0xDC}, // TS11
{0x35, 0xE0, 0x60, 0xE0, 0x60}, // TS12
{0x35, 0x60, 0xE0, 0x60, 0xE0}, // TS13
{0x35, 0xF0, 0x70, 0xF0, 0x70}, // TS14
{0x35, 0x70, 0xF0, 0x70, 0xF0} // TS15
};
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET); // for debug
g_index_ts++;
if (g_index_ts==g_TSC_Max_TimeSlotsToRun)
{
g_current_cycle++;
g_index_ts=0;
}
if (g_current_cycle==2 && g_index_ts==0)
{
g_ready_to_listen = 0;
read_data_finished = 1;
}
if (g_index_ts==0 && g_current_cycle==1)
{
g_ready_to_listen = 1;
}
if (g_current_cycle==1 && g_ready_to_listen && !reading_in_progress)
{
__HAL_SPI_CLEAR_OVRFLAG(&hspi1);
reading_in_progress = 1;
HAL_SPI_Receive_DMA(&hspi1, rx_all_data[g_index_ts], RX_BUFFER_SIZE);
__HAL_TIM_SET_COUNTER(&htim7, 0);
HAL_TIM_Base_Start_IT(&htim7); //POUR le timout de 3 us du dma
}
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET); // for debug
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if( htim->Instance == TIM16)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
if( g_TSC_Phases_To_Run == 0 )
{
HAL_TIM_PWM_Stop_IT(htim, TIM_CHANNEL_1);
}
else
{
if(htim->Instance->RCR>0)
{
htim->Instance->RCR=0;
htim->Instance->CCR1=g_TSC_Long_High_Pulse_Duration-1;
}
else
{
htim->Instance->RCR=(g_TSC_Max_TimeSlotsToRun-1)-1;
htim->Instance->CCR1=g_TSC_Short_High_Pulse_Duration-1;
}
}
if( g_TSC_Phases_To_Run > 0 )
g_TSC_Phases_To_Run--;
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
}
if (htim->Instance == TIM7)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
HAL_TIM_Base_Stop_IT(&htim7);
if (reading_in_progress)
{
HAL_SPI_DMAStop(&hspi1);
reading_in_progress = 0;
is_timeslots_readed[g_index_ts] = 0;
//memset(rx_all_data[g_index_ts], 0, RX_BUFFER_SIZE);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);
}
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
HAL_TIM_Base_Stop_IT(&htim7);
is_timeslots_readed[g_index_ts]=1;
reading_in_progress = 0;
}
I put tim7 for the dma timeout (3 microseconds).
My problem is that:
when i put a breakpoint on read_data_finished = 1; and i have a free run PWM
the output is :
reading_in_progress volatile uint8_t 0 '\0'
g_index_ts volatile uint8_t 0 '\0'
g_current_cycle volatile uint8_t 2 '\002'
read_data_finished volatile uint8_t 0 '\0'
g_ready_to_listen volatile uint8_t 0 '\0'
rx_all_data uint8_t [16][5] 0x20000044 (Hex)
rx_all_data[0] uint8_t [5] 0x20000044 (Hex)
rx_all_data[0][0] uint8_t 0x0 (Hex)
rx_all_data[0][1] uint8_t 0x0 (Hex)
rx_all_data[0][2] uint8_t 0x0 (Hex)
rx_all_data[0][3] uint8_t 0x0 (Hex)
rx_all_data[0][4] uint8_t 0x0 (Hex)
rx_all_data[1] uint8_t [5] 0x20000049 (Hex)
rx_all_data[1][0] uint8_t 0x0 (Hex)
rx_all_data[1][1] uint8_t 0x0 (Hex)
rx_all_data[1][2] uint8_t 0x0 (Hex)
rx_all_data[1][3] uint8_t 0x0 (Hex)
rx_all_data[1][4] uint8_t 0x0 (Hex)
rx_all_data[2] uint8_t [5] 0x2000004e (Hex)
rx_all_data[2][0] uint8_t 0x0 (Hex)
rx_all_data[2][1] uint8_t 0x0 (Hex)
rx_all_data[2][2] uint8_t 0x0 (Hex)
rx_all_data[2][3] uint8_t 0x0 (Hex)
rx_all_data[2][4] uint8_t 0x0 (Hex)
rx_all_data[3] uint8_t [5] 0x20000053 (Hex)
rx_all_data[3][0] uint8_t 0x80 (Hex)
rx_all_data[3][1] uint8_t 0x0 (Hex)
rx_all_data[3][2] uint8_t 0x80 (Hex)
rx_all_data[3][3] uint8_t 0x35 (Hex)
rx_all_data[3][4] uint8_t 0x0 (Hex)
rx_all_data[4] uint8_t [5] 0x20000058 (Hex)
rx_all_data[4][0] uint8_t 0x0 (Hex)
rx_all_data[4][1] uint8_t 0x80 (Hex)
rx_all_data[4][2] uint8_t 0x35 (Hex)
rx_all_data[4][3] uint8_t 0x10 (Hex)
rx_all_data[4][4] uint8_t 0x0 (Hex)
rx_all_data[5] uint8_t [5] 0x2000005d (Hex)
rx_all_data[5][0] uint8_t 0x10 (Hex)
rx_all_data[5][1] uint8_t 0x90 (Hex)
rx_all_data[5][2] uint8_t 0x10 (Hex)
rx_all_data[5][3] uint8_t 0x35 (Hex)
rx_all_data[5][4] uint8_t 0xa0 (Hex)
rx_all_data[6] uint8_t [5] 0x20000062 (Hex)
rx_all_data[6][0] uint8_t 0x0 (Hex)
rx_all_data[6][1] uint8_t 0x0 (Hex)
rx_all_data[6][2] uint8_t 0x0 (Hex)
rx_all_data[6][3] uint8_t 0x0 (Hex)
rx_all_data[6][4] uint8_t 0x0 (Hex)
rx_all_data[7] uint8_t [5] 0x20000067 (Hex)
rx_all_data[7][0] uint8_t 0xa0 (Hex)
rx_all_data[7][1] uint8_t 0x20 (Hex)
rx_all_data[7][2] uint8_t 0x35 (Hex)
rx_all_data[7][3] uint8_t 0x20 (Hex)
rx_all_data[7][4] uint8_t 0x0 (Hex)
rx_all_data[8] uint8_t [5] 0x2000006c (Hex)
rx_all_data[8][0] uint8_t 0xb0 (Hex)
rx_all_data[8][1] uint8_t 0x30 (Hex)
rx_all_data[8][2] uint8_t 0xb0 (Hex)
rx_all_data[8][3] uint8_t 0x0 (Hex)
rx_all_data[8][4] uint8_t 0x0 (Hex)
rx_all_data[9] uint8_t [5] 0x20000071 (Hex)
rx_all_data[9][0] uint8_t 0x30 (Hex)
rx_all_data[9][1] uint8_t 0xb0 (Hex)
rx_all_data[9][2] uint8_t 0x30 (Hex)
rx_all_data[9][3] uint8_t 0x35 (Hex)
rx_all_data[9][4] uint8_t 0xc0 (Hex)
rx_all_data[10] uint8_t [5] 0x20000076 (Hex)
rx_all_data[10][0] uint8_t 0x0 (Hex)
rx_all_data[10][1] uint8_t 0x0 (Hex)
rx_all_data[10][2] uint8_t 0x0 (Hex)
rx_all_data[10][3] uint8_t 0x0 (Hex)
rx_all_data[10][4] uint8_t 0x0 (Hex)
rx_all_data[11] uint8_t [5] 0x2000007b (Hex)
rx_all_data[11][0] uint8_t 0xc0 (Hex)
rx_all_data[11][1] uint8_t 0x40 (Hex)
rx_all_data[11][2] uint8_t 0x35 (Hex)
rx_all_data[11][3] uint8_t 0x40 (Hex)
rx_all_data[11][4] uint8_t 0x0 (Hex)
rx_all_data[12] uint8_t [5] 0x20000080 (Hex)
rx_all_data[12][0] uint8_t 0xd0 (Hex)
rx_all_data[12][1] uint8_t 0x50 (Hex)
rx_all_data[12][2] uint8_t 0xd0 (Hex)
rx_all_data[12][3] uint8_t 0x0 (Hex)
rx_all_data[12][4] uint8_t 0x0 (Hex)
rx_all_data[13] uint8_t [5] 0x20000085 (Hex)
rx_all_data[13][0] uint8_t 0x50 (Hex)
rx_all_data[13][1] uint8_t 0xd0 (Hex)
rx_all_data[13][2] uint8_t 0x50 (Hex)
rx_all_data[13][3] uint8_t 0x35 (Hex)
rx_all_data[13][4] uint8_t 0xe0 (Hex)
rx_all_data[14] uint8_t [5] 0x2000008a (Hex)
rx_all_data[14][0] uint8_t 0x0 (Hex)
rx_all_data[14][1] uint8_t 0x0 (Hex)
rx_all_data[14][2] uint8_t 0x0 (Hex)
rx_all_data[14][3] uint8_t 0x0 (Hex)
rx_all_data[14][4] uint8_t 0x0 (Hex)
rx_all_data[15] uint8_t [5] 0x2000008f (Hex)
rx_all_data[15][0] uint8_t 0xe0 (Hex)
rx_all_data[15][1] uint8_t 0x60 (Hex)
rx_all_data[15][2] uint8_t 0x35 (Hex)
rx_all_data[15][3] uint8_t 0x60 (Hex)
rx_all_data[15][4] uint8_t 0x0 (Hex)
is_timeslots_readed volatile int [16] 0x20000098 <is_timeslots_readed>
is_timeslots_readed[0] volatile int 0
is_timeslots_readed[1] volatile int 0
is_timeslots_readed[2] volatile int 0
is_timeslots_readed[3] volatile int 1
is_timeslots_readed[4] volatile int 0
is_timeslots_readed[5] volatile int 0
is_timeslots_readed[6] volatile int 0
is_timeslots_readed[7] volatile int 0
is_timeslots_readed[8] volatile int 0
is_timeslots_readed[9] volatile int 0
is_timeslots_readed[10] volatile int 1
is_timeslots_readed[11] volatile int 0
is_timeslots_readed[12] volatile int 0
is_timeslots_readed[13] volatile int 0
is_timeslots_readed[14] volatile int 1
is_timeslots_readed[15] volatile int 0
Add new expression
how can i have is_timeslots_readed[15]=0 (that mean dma not finished) and
If i reset and i jumb again on that breakpoint i will probably have something different and when i put uint16_t NumberOfTS_Cycles_to_Run = 2, i have the same problem?
Is there something that did not do correctly?