Other Parts Discussed in Thread: CC1350, CC1310
I am going to create a new thread for this as the discussion is beginning to stray from the original topic.
The original thread is located here CC1310 and CC2640 flash programming via JTAG port.
I am attempting to execute code directly from SRAM in an attempt to create a FLASH boot loader for the CC1310/CC1350 that can be loaded through JTAG (SWD) from another ARM based MCU to allow firmware update/recovery of the CC1310/CC1350 regardless of what state it might be in while requiring a minimum number of connections.
I have been able to, more or less, to accomplish this, however, interrupts are not working correctly.
Basically I created a simple LED blink application that uses a timer interrupt to blink the red and green LEDs on the CC1350.
The application works without any issues when executed from FLASH.
I relocated it to SRAM, and it compiles/links correctly, however, interrupts do not fire.
What I have been able to confirm so far...
I do know interrupts flags are being set correctly by adding this code to the main function:
while(1) { if(TimerIntStatus(GPT0_BASE, TIMER_TIMA_TIMEOUT)) { ISR_TimerInterrupt_Handler(); } }
The complete code is provided below along with the linker script used.
In the thread referenced above I have also provided the map file and other related information. It is a little long so I am trying to avoid duplicating it here.
However, I still don't know why the interrupt is not called when the flag is set.
This is going to be a little on the technical side but I can confirm some registers are set properly...
Register 0xE000ED08 (CPU_SCS_VTOR, the vector relocation register) has a correct value of 0x20001000.
If I pause execution I can bring up these registers, which are associated with the timer, which shows that the interrupt is properly enabled (TATOIM = 1), the interrupt has occurred (TATOMIS = 1), however, the function registered with the interrupt is not being called. PRIMASK is 0x00000000 (global interrupt mask disabled).
Everything seems to be setup correctly, but no interrupt occurs.
Suggestions of where to go from here to try to narrow down this issue would be highly appreciated.
/* * main.c */ #include <stdint.h> #include <stdbool.h> #include <boot_loader.h> #include "driverlib/gpio.h" #include "driverlib/ioc.h" #include "driverlib/prcm.h" #include "driverlib/timer.h" #include "driverlib/sys_ctrl.h" #include "inc/hw_memmap.h" #include "inc/hw_ints.h" void led_setup(void); void ISR_TimerInterrupt_Handler(void); void timer_setup(void); /* * ======== main ======== * Main function */ int main(void) { // setup the LEDs led_setup(); // setup the timer timer_setup(); // enable the master interrupt IntMasterEnable(); // loop forever waiting for an interrupt for(;;); if (bootloaderOpened()) { // Choose between SPI and UART, and do baud rate detection for UART PickInterface(); // Boot loader control loop. Does not return. Update(); } else { // Change the below constant to match the application image intvec start. // vvvvvv asm(" MOV R0, #0x1010 "); // The .resetVecs or .intvecs for the app are // are placed at the constant #0xXXXX address asm(" LDR SP, [R0, #0x0] "); // Load the initial stack pointer asm(" LDR R1, [R0, #0x4] "); // Load the Reset vector address asm(" BX R1 "); // Jump to the application Reset vector } return 0; } /* * ======== led_setup ======== * Setup the red and green LEDs */ void led_setup(void) { // Power on periperal domain PRCMPowerDomainOn(PRCM_DOMAIN_PERIPH); while(PRCMPowerDomainStatus(PRCM_DOMAIN_PERIPH) != PRCM_DOMAIN_POWER_ON); // Power on the GPIO peripheral PRCMPeripheralRunEnable(PRCM_PERIPH_GPIO); PRCMLoadSet(); while ( !PRCMLoadGet() ); // enable output for the red LED GPIO_setOutputEnableDio(IOID_6, GPIO_OUTPUT_ENABLE); // turn on the red LED GPIO_setDio(IOID_6); // enable output for the green LED GPIO_setOutputEnableDio(IOID_7, GPIO_OUTPUT_ENABLE); //turn off the green LED GPIO_clearDio(IOID_7); } /* * ======== ISR_TimerInterrupt_Handler ======== * Interrupt handler to service the TIMER_TIMA_TIMEOUT interrupt. */ void ISR_TimerInterrupt_Handler(void) { // clear interrupt flag TimerIntClear(GPT0_BASE, TIMER_TIMA_TIMEOUT); // toggle the red LED GPIO_toggleDio(IOID_6); // toggle the green LED GPIO_toggleDio(IOID_7); } /* * ======== timer_setup ======== * Function to setup the GPT0 timer. * Using GPT0 timer A, periodic mode * Interrupt callback to ISR_TimerInterrupt_Handler */ void timer_setup(void) { // Power on periperal domain PRCMPowerDomainOn(PRCM_DOMAIN_PERIPH); PRCMLoadSet(); while ( !PRCMLoadGet() ); // Power on the TIMER0 peripheral PRCMPeripheralRunEnable(PRCM_PERIPH_TIMER0); PRCMLoadSet(); while ( !PRCMLoadGet() ); // Enable TIMER0 to continue counting while the MCU sleeps PRCMPeripheralSleepEnable(PRCM_PERIPH_TIMER0); // Configure the TIMER0 TimerConfigure(GPT0_BASE, TIMER_CFG_A_PERIODIC); // Set initial timer value TimerLoadSet(GPT0_BASE, TIMER_A, 0xFFFFFF); // Set prescaler TimerPrescaleSet(GPT0_BASE, TIMER_A, 0x000000FF);//255 // Timer to count on positive clock edge TimerEventControl(GPT0_BASE,TIMER_A,TIMER_EVENT_POS_EDGE); // Be sure the interrupt is clear to start TimerIntClear(GPT0_BASE,TIMER_TIMA_TIMEOUT); // Assign the interrupt handler TimerIntRegister(GPT0_BASE, TIMER_A, ISR_TimerInterrupt_Handler); // Enable the interrupt TimerIntEnable(GPT0_BASE,TIMER_TIMA_TIMEOUT); // Enable the timer TimerEnable(GPT0_BASE,TIMER_A); }
This is the linker file (relevant parts only)
//***************************************************************************** //! @file cc13x0f128.cmd //! @brief CC13x0F128 rev2 linker file for Code Composer Studio. ...
...
... /* Section allocation in memory */ SECTIONS { .intvecs : > RAM_BASE .text : > SRAM .const : > SRAM .constdata : > SRAM .rodata : > SRAM .binit : > SRAM .cinit : > SRAM .pinit : > SRAM .init_array : > SRAM .emb_text : > SRAM .ccfg : > FLASH (HIGH) .vtable : > SRAM .vtable_ram : > SRAM vtable_ram : > SRAM .data : > SRAM .bss : > SRAM .sysmem : > SRAM .stack : > SRAM (HIGH) .nonretenvar : > SRAM .TI.noinit : > SRAM .gpram : > GPRAM #ifdef __TI_COMPILER_VERSION__ #if __TI_COMPILER_VERSION__ >= 15009000 /* Hide section from older compilers not supporting the "ramfunc" attribute. See processors.wiki.ti.com/.../Placing_functions_in_RAM */ .TI.ramfunc : {} load=FLASH, run=SRAM, table(BINIT) #endif #endif } /* Create global constant that points to top of stack */ /* CCS: Change stack size under Project Properties */ __STACK_TOP = __stack + __STACK_SIZE;