Home

Calling a C function from an ISR

E-mail Print PDF
( 1 Vote )
Question: I would like to call a C function from inside an ISR.  How do I do this?

Answer: You can call a C function from inside an ISR by using "lcall _FunctionName".  Any C function when called from assembly requires an underscore before the function name.  So, if you have a C function called MyFunction, in assembly you would call this by using "lcall _Myfunction".  

But just calling the function from inside an ISR does not work.  There are a few very important things to remember when calling a C function from inside an ISR

Preserve and Restore Registers: The compiler could modify A or X registers, Page pointer registers (CUR_PP, IDX_PP, MVW_PP, MVR_PP) and any virtual registers (__r0, __r1, __rx etc) inside the C function.  So, before calling the C function, preserve all these registers and restore them after returning from the C function.   

Set Native Paging: A C function always assumes that the paging mode is native.  But when an ISR is entered, the Flag register is cleared.  This resets the paging mode to Page Mode 0.  So, before calling the C function change the page mode to Native paging.

An example code to call a C function MyFunction from inside a Counter ISR is shown below.

_Counter16_1_ISR:

   ;@PSoC_UserCode_BODY@ (Do not change this line.)
   ;---------------------------------------------------
   ; Insert your custom code below this banner
   ;---------------------------------------------------
   ;   NOTE: interrupt service routines must preserve
   ;   the values of the A and X CPU registers.
   
   push A                               ; Preserve A
   push X                               ; Preserve X
   ISR_PRESERVE_PAGE_POINTERS           ; Preserve all Page pointer registers
   RAM_SET_NATIVE_PAGING                ; Change page mode to Native paging
   RAM_SETPAGE_CUR >__r0                ; Set CUR_PP to point to the RAM page which has virtual registers
   mov A,[__r0]
   push A                               ; Preserve Virtual register __r0
   mov A,[__r1]
   push A                               ; Preserve Virtual register __r1
   
   lcall _MyFunction                    ; Call the C function
   
   RAM_SETPAGE_CUR >__r0                ; Set CUR_PP to point to the RAM page which has virtual registers
   pop A
   mov [__r1],A                         ; Restore Virtual register __r1
   pop A
   mov [__r0],A                        ; Restore Virtual register __r0
   ISR_RESTORE_PAGE_POINTERS            ; Restore all the page pointer registers
   pop X                                ; Restore X
   pop A                                ; Restore A

   ;---------------------------------------------------
   ; Insert your custom code above this banner
   ;---------------------------------------------------
   ;@PSoC_UserCode_END@ (Do not change this line.)

   reti

Important Notes:
  • The above method applies only to ImageCraft compiler.
  • The list of virtual registers that the compiler uses may be found from the .mp file in the Output Files folder in the Project view. 
  • Setting to native paging is required only for devices with more than 256 bytes of RAM.  But in order to make the code portable, add the code that restores native paging even for devices with only 256 bytes of RAM.
  • Preserving and Restoring the paging registers is also required only for devices with more than 256 bytes of RAM.  But in order to make the code portable, add the code that preserves and restores the paging registers even for devices with 256 bytes of RAM

Comments (0)
Only registered users can write comments!