Other Parts Discussed in Thread: CC2541
I am having problems getting timer based interrupts to work properly on the CC2541 (specifically a CC2541 sensor tag). In the interest of full disclosure, I am not using the BTLE stack except for a few pieces of the included HAL to handle initial board setup.
I have done some searching and found a few references indicating that I should look in the sample code provided with the BTLE stack...specifically buzzer.c in the keyfob example. I tried to implement this code (moving it to timer 4 to coincide with the LED on the sensor tag), and it did not make a difference. It should be noted that the example didn't translate completely since I'm not using the OSAL.
Im my attempts to get it working, I have tried to use timer 1, 3 and 4 to PWM an LED as well as fire an interrupt handler with a breakpoint enabled. All with zero success. I am, however, able to get interrupts working on inputs, so I know I'm at least doing something correct.
Anyway, here is the code I'm working with. Please tear it apart:
/**************************************************************************************************
* Includes
**************************************************************************************************/
#include <ioCC2541.h>
#include <hal_defs.h>
#include <hal_board_cfg.h>
/**************************************************************************************************
* FUNCTIONS
**************************************************************************************************/
unsigned int ISR_Counter = 0;
uint16 loop_Counter = 0;
void main(void)
{
// Led 1: 1.0
// Led 2: 0.4
//Button Side: 0.0
//Button 2: 1.6
//Button 3: 1.7
HAL_BOARD_INIT();
/* LED's are outputs and active low */
P1DIR |= BV(0);
P0DIR |= BV(4);
P1_0 = 1;
P0_4 = 1;
/************************************************************/
/*Configure switches as inputs and register interrupts */
// See family user guide for register bit map
/* Side Switch */
P0SEL &= ~(BV(0)); /* Set pin function to GPIO */
P0DIR &= ~(BV(0)); /* Set pin direction to Input */
P0IEN |= BV(0); /* enable interrupt generation at port */
IEN1 |= BV(5); /* enable CPU interrupt for all of port 0*/
P0IFG = ~(BV(0)); /* Clear any pending interrupt */
/* Carbon Switches */
//P1SEL &= ~(BV(6)); /* Set pin function to GPIO */
//P1DIR &= ~(BV(6)); /* Set pin direction to Input */
//P1IEN |= BV(6); /* enable interrupt generation at port */
//IEN2 |= BV(4); /* enable CPU interrupt */
//P1IFG = ~(BV(6)); /* Clear any pending interrupt */
//P1SEL &= ~(BV(7)); /* Set pin function to GPIO */
//P1DIR &= ~(BV(7)); /* Set pin direction to Input */
//P1IEN |= BV(7); /* enable interrupt generation at port */
//IEN2 |= BV(4); /* enable CPU interrupt */
//P1IFG = (uint8)(~(BV(7))); /* Clear any pending interrupt */
/*************************************************************************/
/*Setup the UART */
/* Set UART0 to alternate (UART) mode */
//PERCFG |= BV(0);
/*Give the UART priority on the pins */
//P1DIR |= BV(4)|BV(5);
//P1SEL |= BV(4)|BV(5);
/*UART Mode */
//U0CSR |= BV(7);
/*BAUD rate setting : 9600 ... baud_m = 59 baud_e = 8 for 32 MHz */
//U0GCR |= 8; //BAUD_E
//U0BAUD |= 59; //BAUD_M
//U0GCR |= BV(5);
/*Enable UART receiver */
//U0CSR |= BV(6);
/************************************************************************/
/*setup timer 1 to define the sensor poll period */
//T1CTL &= ~BV(1); //stop the timer (just in case)
/* Modulo mode | tick freq / 128 */
//T1CTL |= BV(2) | BV(3);
/*How high the counter counts before overflowing*/
//T1CC0H = 0x00;
//T1CC0L = 0xFF;
//1. Clear interrupt flags. T2IRQF = ~(1 << 3);
//T1STAT = ~(1 << 5);
//T1IF = 0;
//2. Set individual interrupt-enable bit in the peripherals SFR register, if any.
//T1CCTL0 |= BV(6);
//3. Set the corresponding individual interrupt-enable bit in the IEN0, IEN1, or IEN2 register to 1.
//IEN1 |= BV(1);
/*Clear the flags*/
//T1IF = 0;
//T1OVFIM = 0;
//TIMIF &= ~BV(6);
/* led PWM flicker */
//T1CCTL2 &= ~BV(6);
//P0SEL |= BV(4);
//T1CC2H = 0xFF;
//T1CC2L = 0xFF;
//T1CCTL2 |= BV(3) | BV(4) | BV(5);
//T1CCTL2 |= BV(2); //Compare mode
//T1CCTL2 |= BV(4); //Toggle on compare
//T1CCTL2 |= BV(6);
//T1CTL |= BV(1); //start the timer in modulo mode
//T1IE = 1;
/*************************************************************************/
//Timer 4.0 - led 1.0
P1DIR |= BV(0); // P1_0 = output
P1SEL |= BV(0); // Peripheral function on P1_0
T4CTL &= ~0x10; // Stop timer 44 (if it was running)
T4CTL |= 0x04; // Clear timer 4
T4CTL &= ~0x08; // Disable Timer 4 overflow interrupts
T4CTL |= 0x02; // Timer 3 mode = 4 - Modulo
T4CCTL0 &= ~0x40; // Disable channel 0 interrupts
T4CCTL0 |= 0x04; // Ch0 mode = compare
T4CCTL0 |= 0x10; // Ch0 output compare mode = toggle on compare
// Update registers
T4CTL |= BV(5) | BV(6) | BV(7);
T4CC0 = (uint8)255;
// Start timer
T4CTL |= BV(4);
/************************************************************************/
HAL_ENABLE_INTERRUPTS();
while(1){
// U0DBUF = T1CNTL;
if (loop_Counter == 0){ //P0_4 ^= 1; }
loop_Counter++;
}
}
/**************************************************************************************************
CALL-BACKS
**************************************************************************************************/
/*Side Switch button */
_PRAGMA(vector=P0INT_VECTOR)
__interrupt void port0_ISR(void)
{
if ( P0IFG & BV(0) ) //If interrupt source is switch 0.0
{
P1_0 ^= 1; // P1.0 = toggle
}
ISR_Counter++;
//Clear the CPU interrupt flag for Port_0 PxIFG has to be cleared before PxIF
P0IFG = 0;
P0IF = 0;
}
/*Timer 4 interrupt */
_PRAGMA(vector=T4_VECTOR)
__interrupt void T4_ISR(void)
{
P1_0 ^= 1; // P1.0 = toggle
}
/*************************************************************************************************
**************************************************************************************************/