2020-10-01 02:47 AM
MCU STM32L431, SYSCLK 80MHz
The callback takes 1.5us to fire from pin drop, and the callback functions take long time to execute as I show the image
the pin config function
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, Led1_Pin|Led2_Pin, GPIO_PIN_SET);
/*Configure GPIO pins : Led1_Pin Led2_Pin */
GPIO_InitStruct.Pin = Led1_Pin|Led2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : SPI1_NSS_Pin */
GPIO_InitStruct.Pin = SPI1_NSS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(SPI1_NSS_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : SPI1_SCK_ST_Pin */
GPIO_InitStruct.Pin = SPI1_SCK_ST_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(SPI1_SCK_ST_GPIO_Port, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
}
and callback function,
/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
HAL_GPIO_WritePin(GPIOC, Led1_Pin, GPIO_PIN_SET);
// detect the SPI setting of the C2200, 1Mg bit or 200K bit
// SPI_PHASE_2EDGE, SPI_POLARITY_HIGH
if(HAL_GPIO_ReadPin(SPI1_SCK_ST_GPIO_Port, SPI1_SCK_ST_Pin))
{
const uint16_t CR1 = 0x0243;
WRITE_REG(hspi1.Instance->CR1, CR1);
}
// SPI_PHASE_1EDGE, SPI_POLARITY_LOW
else
{
const uint16_t CR1 = 0x0240;
WRITE_REG(hspi1.Instance->CR1, CR1);
}
HAL_GPIO_WritePin(GPIOC, Led1_Pin, GPIO_PIN_RESET);
}
/* USER CODE END 4 */
I suppose that at 80 MHz speed it should take a few nano seconds to trigger to callback function and execute the callback functions into a very short time
thanks in advance for your support
2020-10-01 07:32 AM
Each tick takes 12.5 nanoseconds, how is it going to start the interrupt in a "few nano seconds"?
HAL_GPIO_EXTI_Callback is called indirectly from the interrupt. If you need a faster response, you'll have to discard the HAL handlers and write your own. Broadly speaking, interrupts start something like 10-20ticks after the actual event, sometimes more. The processor needs to push registers onto the stack before it can start the interrupt, this is not instantaneous.
2020-10-01 07:54 AM
Thank you, I was afraid of it
where can I get the assembly code instructions manual to see if I'm able to try to solve this, and a reference guide to implement it?
best regards
2020-10-02 04:57 AM
hi all,
If it could help to any other, finally I half solved by this:
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
#if 0
/* EXTI line interrupt detected */
if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
HAL_GPIO_EXTI_Callback(GPIO_Pin);
}
#else
if(*((unsigned int *)0x40010414) & 0x0010)
{
// detect the SPI setting of the C2200, 1Mg bit or 200K bit
// SPI_PHASE_2EDGE, SPI_POLARITY_HIGH
if ((*((unsigned int *)0x48000410) & 0x0010) != 0x00u)
*((unsigned int *)0x40013000) = 0x0243;
// SPI_PHASE_1EDGE, SPI_POLARITY_LOW
else
*((unsigned int *)0x40013000) = 0x0240;
*((unsigned int *)0x40010414) = 0x0010;
*((unsigned int *)0x48000818) = 0x4000;
*((unsigned int *)0x48000828) = 0x4000;
}
#endif
}
Passing all the registers to absolute address, each instruction take about 100 nSeg, but time to trigger take about 300 nSeg
Into ideally solutions it should be double faster, if there are a faster solutions I'll be sow glad to know.
Have a good weekend.
2020-10-02 12:20 PM
Use register level code, call EXTI ISR directly not through HAL handler and enable code optimization for speed.
2020-10-05 04:37 AM
Thanks
When you say "call EXTI ISR directly" I understand to place the user code betwen the /* USER CODE BEGIN EXTI4_IRQn 0 */ and /* USER CODE END EXTI4_IRQn 0 */ into void EXTI4_IRQHandler(void) function, outside of "HAL_GPIO_EXTI_IRQHandler".
void EXTI4_IRQHandler(void)
{
/* USER CODE BEGIN EXTI4_IRQn 0 */
*((unsigned int *)0x48000818) = 0x4000;
// detect the SPI setting of the C2200, 1Mg bit or 200K bit
// SPI_PHASE_2EDGE, SPI_POLARITY_HIGH
if ((*((unsigned int *)0x48000410) & 0x0010) != 0x00u)
*((unsigned int *)0x40013000) = 0x0243;
// SPI_PHASE_1EDGE, SPI_POLARITY_LOW
else
*((unsigned int *)0x40013000) = 0x0240;
*((unsigned int *)0x48000828) = 0x4000;
/* USER CODE END EXTI4_IRQn 0 */
/* beyond this point the function could take as long as it need */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
/* USER CODE BEGIN EXTI4_IRQn 1 */
/* USER CODE END EXTI4_IRQn 1 */
}
It seems it is going to solve the issue, now the user code take up to 95 nSeg that is very correct.
The trigger take up to 750 nSeg, it still being quite long, a nice target should be about 500 nSeg.
if there are any trick to scratch a few more nanoseconds I'll be so glad to known, now it seems to work but time to time, still showing some misplaced data.
Thanks again