Hi all,
I'm getting started in ARM (AM1808) and I'm trying to get a timer interrupt to trigger system event scheduler. Currently it should only blink a buzzer.
I've followed the StarterWare 1.00.03.03 example (timerCounter.c), but the system is not generating interrupts. I currently only have one enabled (Timer2 12). I've looked at the registers and verified that the interrupt is set up correctly, e.g. mapped to a channel, IRQ enabled in CPSR, service routine registered, etc.
Any ideas? Code is below, though currently the Interrupt set up in "configure_timer()" is commented out.
/*
* main.c
*/
//StarterWare
#include "psc.h"
#include "gpio.h"
#include "cpu.h"
#include "timer.h"
#include "interrupt.h"
#include "soc_AM1808.h"
//#include "evmAM1808.h"
#include "hw_syscfg0_AM1808.h"
#include "main.h"
//See GPIO Registry structure in TRM for pin numbers
#define GPIO_4_0 65
#define GPIO_4_1 66
#define GPIO_0_1 2
#define GPIO_2_15 48
#define DELAY_RELOAD 24000000
#define BUZZER_DURATION 87500
static void configure_gpio(void);
static void configure_timer(void);
static void isr_timer(void);
unsigned int timer_tick =0;
unsigned int led_timer;
unsigned int buzzer_timer;
unsigned int foo;
int main(void) {
//CPU should be in privileged mode after boot due to code in boot.asm
unsigned int foo = 0;
//unsigned int delay = DELAY_RELOAD;
//GPIO Power set up
//GPIO are commanded by PSC1, have a Local PSC number = 3, are always on, and and the next state should be enabled
foo = PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
if(foo){
while(1); //something's wrong, hang system
}
//Configure the GPIO for the LEDs
configure_gpio();
GPIOPinWrite(SOC_GPIO_0_REGS, GPIO_0_1, GPIO_PIN_LOW);
GPIOPinWrite(SOC_GPIO_0_REGS, GPIO_4_0, GPIO_PIN_LOW);
GPIOPinWrite(SOC_GPIO_0_REGS, GPIO_4_1, GPIO_PIN_LOW);
led_timer = 1;
//Configure the timers
configure_timer();
TimerEnable(SOC_TMR_2_REGS, TMR_TIMER12, TMR_ENABLE_CONT);
//CPUSwitchToUserMode();
while(1){
foo = TimerCounterGet(SOC_TMR_2_REGS, TMR_TIMER12);
//check if timer is running, it is
if(foo>=(DELAY_RELOAD>>1)){
GPIOPinWrite(SOC_GPIO_0_REGS, GPIO_4_1, GPIO_PIN_HIGH);
} else {
GPIOPinWrite(SOC_GPIO_0_REGS, GPIO_4_1, GPIO_PIN_LOW);
}
//debugging
/* foo = IntSystemStatusRawGet(2);
if(foo){
GPIOPinWrite(SOC_GPIO_0_REGS, GPIO_4_0, GPIO_PIN_HIGH);
} else {
GPIOPinWrite(SOC_GPIO_0_REGS, GPIO_4_0, GPIO_PIN_LOW);
}
foo = TimerIntStatusGet(SOC_TMR_2_REGS,TMR_INT_TMR12_NON_CAPT_MODE);
if(timer_tick){
GPIOPinWrite(SOC_GPIO_0_REGS, GPIO_4_0, GPIO_PIN_HIGH);
} else {
GPIOPinWrite(SOC_GPIO_0_REGS, GPIO_4_0, GPIO_PIN_LOW);
}*/
// while(delay){
// delay--;
// if(delay == 0) timer_tick = 1;
// }
//TODO let's set up a timer instead of the soft timer
/* if(timer_tick){
if(led_timer){
led_timer--;
if(led_timer == 0){
change_leds();
led_timer = 1;
}
}
if(buzzer_timer){
buzzer_timer--;
if(buzzer_timer == 0){
change_buzzer();
buzzer_timer = 1;
}
}
delay = DELAY_RELOAD;
}*/
}
}
static void configure_gpio(void){
//Pin Mux Set up
//Kick unlock
// unlock the system config registers.
//May not be needed, I believe we're using rev 2 silicon
//can verify by reading DEVID0 MSBit
//MSB(DEVID0) = 0 -> Rev 1, need to use
//MSB(DEVID0) = 1 -> Rev 2, no need to use
if(SYSCONFIG0->DIEIDR[0]&0x80000000){
SYSCONFIG0->KICKR[0] = KICK0R_UNLOCK;
SYSCONFIG0->KICKR[1] = KICK1R_UNLOCK;
}
CLRBIT(SYSCONFIG0->PINMUX[10], 0xF0000000); //clear the pinmux reg for GP4[0]
SETBIT(SYSCONFIG0->PINMUX[10], 0x80000000); //set it to be GPIO
CLRBIT(SYSCONFIG0->PINMUX[10], 0x0F000000); //clear the pinmux reg for GP4[1]
SETBIT(SYSCONFIG0->PINMUX[10], 0x08000000); //set it to be GPIO
CLRBIT(SYSCONFIG0->PINMUX[1], 0x0F000000); //clear the pinmux reg for GP0[1]
SETBIT(SYSCONFIG0->PINMUX[1], 0x08000000); //set it to be GPIO
CLRBIT(SYSCONFIG0->PINMUX[5], 0x0000000F); //clear the pinmux reg for GP2[15]
SETBIT(SYSCONFIG0->PINMUX[5], 0x00000008); //set it to be GPIO
//disable PU/PD
CLRBIT(SYSCONFIG1->PUPDENA, 0x00044004); //clear (disable) Pull-ups on pin groups C[18], C[15] and C[2]
// lock the system config registers.
if(SYSCONFIG0->DIEIDR[0]&0x80000000){
SYSCONFIG0->KICKR[0] = KICK0R_LOCK;
SYSCONFIG0->KICKR[1] = KICK1R_LOCK;
}
//GPIO4_0 is pin 65, see ref document
GPIODirModeSet(SOC_GPIO_0_REGS, GPIO_0_1, GPIO_DIR_OUTPUT);
GPIODirModeSet(SOC_GPIO_0_REGS, GPIO_4_0, GPIO_DIR_OUTPUT);
GPIODirModeSet(SOC_GPIO_0_REGS, GPIO_4_1, GPIO_DIR_OUTPUT);
}
static void configure_timer(void){
//s unsigned int temp;
TimerConfigure(SOC_TMR_2_REGS, TMR_CFG_64BIT_CLK_INT); //Set timer2 to dual 32-bit mode, both halves set to internal clocking
//Want 1ms time out, so need to figure out what the internal clock freq is to set this prescaler
//Currently using 24Mhz system clock, delay reload at 24M -> 1sec pulse
TimerPeriodSet(SOC_TMR_2_REGS, TMR_TIMER12, DELAY_RELOAD); //set the period of the timer
/* TimerIntEnable(SOC_TMR_2_REGS, TMR_INT_TMR12_NON_CAPT_MODE);
IntAINTCInit(); //Initialize the interrupt controller
IntRegister(SYS_INT_TIMR2_ALL, isr_timer); //bind the function isr_timer to TIMER2 interrupts
IntChannelSet(SYS_INT_TIMR2_ALL, 2); //sets channel number for timer interrupt, maps to IRQ
IntGlobalEnable(); //Enable global interrupts AINTC
if(SYSCONFIG0->DIEIDR[0]&0x80000000){
SYSCONFIG0->KICKR[0] = KICK0R_UNLOCK;
SYSCONFIG0->KICKR[1] = KICK1R_UNLOCK;
}
IntMasterIRQEnable(); //Enable IRQ in the CPSR, needs privileged mode
// lock the system config registers.
if(SYSCONFIG0->DIEIDR[0]&0x80000000){
SYSCONFIG0->KICKR[0] = KICK0R_LOCK;
SYSCONFIG0->KICKR[1] = KICK1R_LOCK;
}
//not set
IntIRQEnable(); //Enable IRQ in AINTC
IntSystemEnable(SYS_INT_TIMR2_ALL); //Enable the timer interrupt in AINTC
temp = IntChannelGet(SYS_INT_TIMR2_ALL);
temp = temp;*/
}
static void isr_timer(void){
TimerIntDisable(SOC_TMR_2_REGS, TMR_INT_TMR12_NON_CAPT_MODE); //Disable the timer2 normal interrupt
IntSystemStatusClear(SYS_INT_TIMR2_ALL); //Clear the timer2 interrupt
TimerIntStatusClear(SOC_TMR_2_REGS, TMR_INT_TMR12_NON_CAPT_MODE); //clear the timer2 normal interrupt
//timer_tick = 1; //Flag the application to do its dance
if(timer_tick){
timer_tick = 0;
} else {
timer_tick = 1;
}
TimerIntEnable(SOC_TMR_2_REGS, TMR_INT_TMR12_NON_CAPT_MODE); //Enable the timer2 interrupt again
}