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;

