Recent

Author Topic: STM32 interrupts  (Read 4996 times)

petex

  • Jr. Member
  • **
  • Posts: 69
STM32 interrupts
« on: March 05, 2021, 04:45:52 pm »
hello,
I am trying to enable interrupts on the STM32 bluepill with the MBR framework and compiler.

I was trying to enable a character received interrupt on the uart1. When I press a key at the terminal I get an interrupt generated but it doesn't hit a breakpoint on the interrupt handler. I get vectored into the file "cortexm3_start.inc" which generally happens for any hardware fault.

The library calls are in "stm32f103fw.pas" which is a c to pascal conversion of the STM library.

As far as i can see there is no general documentation on this subject so the code has been constructed from what i can extract from tinternet. Why is this not working ???

A question :-
The interrupt handlers have alias names - are these essential or meant to be helpful ? I would have thought essential as how else is the handler code tied into the interrupt vector table. But am i using the right name ?


the initialisation code is as follows:

Code: Pascal  [Select][+][-]
  1.  
  2. procedure init_uart_intr;
  3. const
  4.     USART1_IRQn                 = 37;  
  5. begin
  6.  
  7.     USART_ITConfig(USART1, USART_IT_RXNE, TState.Enabled);
  8.  
  9.     NVIC.ISER[USART1_IRQn shr 5] := 1 shl (USART1_IRQn and $1F); //Enable Interrupt
  10.  

the interrupt handler is:-

Code: Pascal  [Select][+][-]
  1. procedure UART_interrupt; public name 'USART1_global_interrupt'; interrupt;
  2. var
  3.      b : byte;
  4. begin
  5.      if USART_GetITStatus(USART1, USART_IT_RXNE)  then
  6.             b := USART_ReceiveData(USART1);
  7.  
  8.     USART_ClearITPendingBit(USART1, USART_IT_RXNE)
  9. end;
  10.  
  11.  

edit:
I get a breakpoint at "_PendSV_Handler " location in the vector table
« Last Edit: March 05, 2021, 05:31:21 pm by petex »

MiR

  • Full Member
  • ***
  • Posts: 246
Re: STM32 interrupts
« Reply #1 on: March 05, 2021, 05:50:08 pm »
I am guessing here that you use -Wpbluepill to select the bluepill

Have a look at the code for the stm32f103rb:

procedure USART1_IRQHandler; external name 'USART1_IRQHandler';
procedure USART2_IRQHandler; external name 'USART2_IRQHandler';
procedure USART3_IRQHandler; external name 'USART3_IRQHandler';


I case you used -Wpstm32f10x (do not know the exact name here) then

procedure USART1_global_interrupt; external name 'USART1_global_interrupt';
procedure USART2_global_interrupt; external name 'USART2_global_interrupt';
procedure USART3_global_interrupt; external name 'USART3_global_interrupt';

can be found in the unit file for the chip.

This difference comes from the fact that the headers I created are automagically converted from CMSIS Sources and for that reason they are available for close to all cortex-m* chips available from ST today.

The older Headers were hand-crafted (I guess) so they do not follow the naming that is used in the CMSIS sources and may even be older than the CMSIS standard (which, when I remmber correctly was established when Arm bought Keil)

So it may very well be that you are now suffering from living in two worlds....

I started abstracting those differences in mbf-freertos as they are a pain when trying to develop with one sourcecode for several processors, check here how I have done it in MBF-Freertos:

https://github.com/michael-ring/mbf-freertos/blob/master/source/MBF.STM32F4.UART.pas


MiR
« Last Edit: March 05, 2021, 05:52:38 pm by MiR »

petex

  • Jr. Member
  • **
  • Posts: 69
Re: STM32 interrupts
« Reply #2 on: March 05, 2021, 06:32:34 pm »
ok thanks.

I changed the interrupt handler header to

Code: Pascal  [Select][+][-]
  1. procedure USART1_IRQHandler; interrupt; public name 'USART1_IRQHandler';
  2. var
  3.      b : byte;
  4. begin
  5.  
  6.     if USART_GetFlagStatus(USART1,USART_FLAG_RXNE) then
  7.             b := USART_ReceiveData(USART1);
  8.  
  9.     USART_ClearITPendingBit(USART1, USART_IT_RXNE)
  10. end;
  11.      
  12.  

and  that did the trick. I get a breakpoint at my interrupt handler and it returns ok.

Is there a list of these alternative interrupt names or the file location ? thanks


And yes I am in two worlds ... I am using the MBF stuff as much as possible, but I need to dip into the STM32 library c to pascal conversion for missing bits.

MiR

  • Full Member
  • ***
  • Posts: 246
Re: STM32 interrupts
« Reply #3 on: March 05, 2021, 06:46:42 pm »
This directory has all the unit files for supported chips:

https://github.com/michael-ring/freepascal/tree/master/rtl/embedded/arm

This is the original of fpc-trunk:

https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/rtl/embedded/arm/

when you want to see the file mapping which header actually gets used (there are some cases where this helps) look here:

https://github.com/michael-ring/freepascal/blob/master/compiler/arm/cpuinfo.pas

look for controllerunitstr

MiR

« Last Edit: March 05, 2021, 06:49:30 pm by MiR »

petex

  • Jr. Member
  • **
  • Posts: 69
Re: STM32 interrupts
« Reply #4 on: March 06, 2021, 01:38:39 pm »
ok thanks

I have a hypothetical question here. From what I can see in the code - shown below - Is that the interrupt vector table has some gaps in it and is populated with nil pointers in places.
What would I need to do to extend this. For example if I was using the second uart and I wanted to have an interrupt handler for it.
I would need....
Code: Pascal  [Select][+][-]
  1. procedure USART2_IRQHandler; external name 'USART2_IRQHandler';
  2.  
and an entry ..
Code: Pascal  [Select][+][-]
  1. etc. etc. etc.....
  2. .long I2C1_IRQHandler
  3.   .long 0
  4.   .long SPI1_IRQHandler
  5.   .long 0
  6.   .long USART1_IRQHandler
  7.   .long USART2_IRQHandler    <<<<<<<------------------------
  8.  
  9.  

or for example if i wanted to patch in a "Memory Manage" interrupt where there is currently a nil

Code: Pascal  [Select][+][-]
  1.  
  2. procedure NonMaskableInt_Handler; external name 'NonMaskableInt_Handler';
  3. procedure HardFault_Handler; external name 'HardFault_Handler';
  4. procedure SVC_Handler; external name 'SVC_Handler';
  5. procedure PendSV_Handler; external name 'PendSV_Handler';
  6. procedure SysTick_Handler; external name 'SysTick_Handler';
  7. procedure WWDG_IRQHandler; external name 'WWDG_IRQHandler';
  8. procedure RTC_IRQHandler; external name 'RTC_IRQHandler';
  9. procedure FLASH_IRQHandler; external name 'FLASH_IRQHandler';
  10. procedure RCC_IRQHandler; external name 'RCC_IRQHandler';
  11. procedure EXTI0_1_IRQHandler; external name 'EXTI0_1_IRQHandler';
  12. procedure EXTI2_3_IRQHandler; external name 'EXTI2_3_IRQHandler';
  13. procedure EXTI4_15_IRQHandler; external name 'EXTI4_15_IRQHandler';
  14. procedure DMA1_Channel1_IRQHandler; external name 'DMA1_Channel1_IRQHandler';
  15. procedure DMA1_Channel2_3_IRQHandler; external name 'DMA1_Channel2_3_IRQHandler';
  16. procedure DMA1_Channel4_5_IRQHandler; external name 'DMA1_Channel4_5_IRQHandler';
  17. procedure ADC1_IRQHandler; external name 'ADC1_IRQHandler';
  18. procedure TIM1_BRK_UP_TRG_COM_IRQHandler; external name 'TIM1_BRK_UP_TRG_COM_IRQHandler';
  19. procedure TIM1_CC_IRQHandler; external name 'TIM1_CC_IRQHandler';
  20. procedure TIM2_IRQHandler; external name 'TIM2_IRQHandler';
  21. procedure TIM3_IRQHandler; external name 'TIM3_IRQHandler';
  22. procedure TIM14_IRQHandler; external name 'TIM14_IRQHandler';
  23. procedure TIM16_IRQHandler; external name 'TIM16_IRQHandler';
  24. procedure TIM17_IRQHandler; external name 'TIM17_IRQHandler';
  25. procedure I2C1_IRQHandler; external name 'I2C1_IRQHandler';
  26. procedure SPI1_IRQHandler; external name 'SPI1_IRQHandler';
  27. procedure USART1_IRQHandler; external name 'USART1_IRQHandler';
  28.  
  29.  
  30. {$i cortexm0_start.inc}
  31.  
  32. procedure Vectors; assembler; nostackframe;
  33. label interrupt_vectors;
  34. asm
  35.   .section ".init.interrupt_vectors"
  36.   interrupt_vectors:
  37.   .long _stack_top
  38.   .long Startup
  39.   .long NonMaskableInt_Handler
  40.   .long HardFault_Handler
  41.   .long 0
  42.   .long 0
  43.   .long 0
  44.   .long 0
  45.   .long 0
  46.   .long 0
  47.   .long 0
  48.   .long SVC_Handler
  49.   .long 0
  50.   .long 0
  51.   .long PendSV_Handler
  52.   .long SysTick_Handler
  53.   .long WWDG_IRQHandler
  54.   .long 0
  55.   .long RTC_IRQHandler
  56.   .long FLASH_IRQHandler
  57.   .long RCC_IRQHandler
  58.   .long EXTI0_1_IRQHandler
  59.   .long EXTI2_3_IRQHandler
  60.   .long EXTI4_15_IRQHandler
  61.   .long 0
  62.   .long DMA1_Channel1_IRQHandler
  63.   .long DMA1_Channel2_3_IRQHandler
  64.   .long DMA1_Channel4_5_IRQHandler
  65.   .long ADC1_IRQHandler
  66.   .long TIM1_BRK_UP_TRG_COM_IRQHandler
  67.   .long TIM1_CC_IRQHandler
  68.   .long TIM2_IRQHandler
  69.   .long TIM3_IRQHandler
  70.   .long 0
  71.   .long 0
  72.   .long TIM14_IRQHandler
  73.   .long 0
  74.   .long TIM16_IRQHandler
  75.   .long TIM17_IRQHandler
  76.   .long I2C1_IRQHandler
  77.   .long 0
  78.   .long SPI1_IRQHandler
  79.   .long 0
  80.   .long USART1_IRQHandler
  81.  
  82.  

Laksen

  • Hero Member
  • *****
  • Posts: 724
    • J-Software
Re: STM32 interrupts
« Reply #5 on: March 06, 2021, 02:13:16 pm »
If the interrupt table is incorrect you should report that as a bug

MiR

  • Full Member
  • ***
  • Posts: 246
Re: STM32 interrupts
« Reply #6 on: March 06, 2021, 02:17:20 pm »
From which chip is this irq table? Smaller chips of a family sometimes have less peripherals.. so entries beeing set to 0 is correct.

As Laksen wrote, it is either a bug or the chip has only one IRQ capable UART or the Interrupt is shared. But the key to sort this out is to know which file you looked at and for which chip you wanted to check.


petex

  • Jr. Member
  • **
  • Posts: 69
Re: STM32 interrupts
« Reply #7 on: March 06, 2021, 03:07:35 pm »
i think its a bug on my part :o

Its confusing cos there are so many variants !

For a STM32F103C8T6 i am looking at
https://github.com/michael-ring/freepascal/blob/master/rtl/embedded/arm/stm32f10x_md.pp

which seems to have the 3 usarts defined. Sorry for that.

MiR

  • Full Member
  • ***
  • Posts: 246
Re: STM32 interrupts
« Reply #8 on: March 06, 2021, 03:27:13 pm »
This is why it is usefull to check cpuinfo.pas.

Assume you want to see what is used for -Wpbluepill, check for this line:

      (controllertypestr:'BLUEPILL'            ; controllerunitstr:'STM32F103XB'         ; cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00005000),


and you will see that the matching file is STM32F103XB which also has all three uart interrupts defined:

procedure USART1_IRQHandler; external name 'USART1_IRQHandler';
procedure USART2_IRQHandler; external name 'USART2_IRQHandler';
procedure USART3_IRQHandler; external name 'USART3_IRQHandler';

petex

  • Jr. Member
  • **
  • Posts: 69
Re: STM32 interrupts
« Reply #9 on: March 06, 2021, 09:08:34 pm »
I notice that the STM description of the STM32F103C8T6 says that flash memory can be 64 or 128 kBytes. The GDB debugger reports flash memory size of 128 kbytes for my card.

The definition in CPUINFO.pas has a size of 64 kBytes and I cannot build a system bigger than 64 kbytes (the linker complains).

Is there a way of getting around this ?

Laksen

  • Hero Member
  • *****
  • Posts: 724
    • J-Software
Re: STM32 interrupts
« Reply #10 on: March 06, 2021, 09:30:34 pm »
STM32F103C8T6 has 64 kB of flash. STM32F103CBT6 has 128 kB of flash

If you want to compile for STM32F103CBT6 you should use -WpSTM32F103XB

MiR

  • Full Member
  • ***
  • Posts: 246
Re: STM32 interrupts
« Reply #11 on: March 06, 2021, 09:30:41 pm »
Petex: What you are writing is not fully correct:

STM32F103C8T6 is always only 64kb.
STM32F103CBT6 is 128mb.

however, afaik the chips are the same and those that did not pass vertification for 128kB were downgraded to 64kB, but have actually 128kkB on Board.

I may be wrong here in the details, never cared much for stm32f1 line so others may better know the real story.

so when you compile with STM32F103CBT6 as target the created binary will use up to 128kb.

there is a last hurdle, every chip has a chip id and when programming the chip most tools will likely fail. But I saw instructions on how to overcome this hurdle.

But I strongly doubt that all the fuss is worth it.

There are cheap black pills that are far more potent and cost rougly the the same. 

 

TinyPortal © 2005-2018