All,
I wrote some code for the eZdsp C5505 stick. This code should toggle GP21 every second. I find that once I try to enter IDLE3 mode I stop receiving the RTC interrupt. If I do not disable the PLL it seems to work. Can someone please let me know what I am doing wrong?
Cheers!
#include <stdio.h>
#include <tistdtypes.h>
#include "csl_intc.h"
#define USE_EVAL_STICK (1)
extern void VECSTART(void); // CSL asm file
volatile ioport Uint16 * ICR = (volatile Uint16 *) 0x0001;
volatile ioport Uint16 * TCR0 = (volatile Uint16 *) 0x1810;
volatile ioport Uint16 * RTCPMGT = (volatile Uint16 *) 0x1930;
volatile ioport Uint16 * EBSR = (volatile Uint16 *) 0x1C00;
volatile ioport Uint16 * PCGCR1 = (volatile Uint16 *) 0x1C02;
volatile ioport Uint16 * PCGCR2 = (volatile Uint16 *) 0x1C03;
volatile ioport Uint16 * PSRCR = (volatile Uint16 *) 0x1C04;
volatile ioport Uint16 * PRCR = (volatile Uint16 *) 0x1C05;
volatile ioport Uint16 * USBSCR = (volatile Uint16 *) 0x1C32;
volatile ioport Uint16 * CLKSTOP = (volatile Uint16 *) 0x1C3A;
volatile ioport Uint16 * CGCR1 = (volatile Uint16 *) 0x1C20;
volatile ioport Uint16 * CGCR2 = (volatile Uint16 *) 0x1C21;
volatile ioport Uint16 * CGCR3 = (volatile Uint16 *) 0x1C22;
volatile ioport Uint16 * CGCR4 = (volatile Uint16 *) 0x1C23;
volatile ioport Uint16 * CCR2 = (volatile Uint16 *) 0x1C1F;
volatile ioport Uint16 * IODIR1 = (volatile Uint16 *) 0x1C06;
volatile ioport Uint16 * IODATAOUT1 = (volatile Uint16 *) 0x1C0A;
volatile ioport Uint16 * IOINTEN1 = (volatile Uint16 *) 0x1C0E;
volatile ioport Uint16 * IODIR2 = (volatile Uint16 *) 0x1C07;
volatile ioport Uint16 * IODATAOUT2 = (volatile Uint16 *) 0x1C0B;
volatile ioport Uint16 * IOINTEN2 = (volatile Uint16 *) 0x1C0F;
volatile ioport Uint16 * RTCINTEN = (volatile Uint16 *) 0x1900;
volatile ioport Uint16 * RTCUPDATE = (volatile Uint16 *) 0x1901;
volatile ioport Uint16 * RTCMIL = (volatile Uint16 *) 0x1904;
volatile ioport Uint16 * RTCSEC = (volatile Uint16 *) 0x1908;
volatile ioport Uint16 * RTCMIN = (volatile Uint16 *) 0x190C;
volatile ioport Uint16 * RTCHOUR = (volatile Uint16 *) 0x1910;
volatile ioport Uint16 * RTCDAY = (volatile Uint16 *) 0x1914;
volatile ioport Uint16 * RTCMONTH = (volatile Uint16 *) 0x1918;
volatile ioport Uint16 * RTCYEAR = (volatile Uint16 *) 0x191C;
volatile ioport Uint16 * RTCINTFL = (volatile Uint16 *) 0x1920;
volatile ioport Uint16 * RTCINTREG = (volatile Uint16 *) 0x1924;
// borrowed from CSL
#define CSL_SYS_CGCR1_RESETVAL (0x1000u)
#define CSL_SYS_CGICR_RESETVAL (0x0000u)
#define CSL_SYS_CGOCR_RESETVAL (0x0000u)
#define CSL_SYS_CGCR2_RESETVAL (0x0806u)
static Uint8 bPllBypass = 0;
void configure_pll(void)
{
Uint16 timeout = 1000;
// Bypass the PLL
*CCR2 = 0x0000;
// Reset PLL register
*CGCR1 = CSL_SYS_CGCR1_RESETVAL;
*CGCR2 = CSL_SYS_CGICR_RESETVAL;
*CGCR4 = CSL_SYS_CGOCR_RESETVAL;
*CGCR3 = CSL_SYS_CGCR2_RESETVAL;
// Set CLR_CTRL = 0 in CGCR1
*CGCR1 &= 0x7FFF;
*CGCR2 = 0x8000;
*CGCR4 = 0x0000;
*CGCR3 = 0x0806;
// Set PLL_PWRDN = 0, PLL_STANDBY = 0, CLR_CNTL = 1 and program MH in CGCR1
// according to your required settings
*CGCR1 = 0x8BE8;
while (!(*CGCR3&0x0008) && timeout--)
{
}
// Select pll
*CCR2 = 0x0001;
return;
}
void configure_io_toogle(void)
{
#ifdef USE_EVAL_STICK
// Toggle GPIO21
// Set GP21 instead of A[15]
*EBSR |= 0x0001;
// disable interrupt
// set IO high and enable as output
*IOINTEN2 &= 0xFFDF;
*IODATAOUT2 |= 0x0020;
*IODIR2 |= 0x0020;
#else
// toggle GPIO14
// disable interrupt
// set IO high and enable as output
*IOINTEN1 &= 0xBFFF;
*IODATAOUT1 |= 0x4000;
*IODIR1 |= 0x4000;
#endif
}
void toggle_io(void)
{
static Uint8 setval = 1;
if ( setval )
{
#ifdef USE_EVAL_STICK
*IODATAOUT2 &= 0xFFDF;
#else
*IODATAOUT1 &= 0xBFFF;
#endif
setval = 0;
}
else
{
#ifdef USE_EVAL_STICK
*IODATAOUT2 |= 0x0020;
#else
*IODATAOUT1 |= 0x4000;
#endif
setval = 1;
}
}
interrupt void rtc_isr(void)
{
Uint16 delay ;
if ( bPllBypass )
{
*ICR = 0x00E0; // enable idle on all domains
asm(" nop");
asm(" idle");
asm(" nop");
// enable the pll again
configure_pll();
*RTCINTFL = *RTCINTFL;
bPllBypass = 0;
}
else
{
// clear interrupt flag register to all for interrupts to fire again
*RTCINTFL = *RTCINTFL;
}
}
void configure_rtc(void)
{
Uint8 timeOut = 1000;
// Configure and enable the RTC interrupts using INTC module
IRQ_globalDisable();
// Clear any pending interrupts
IRQ_clearAll();
// Disable all the interrupts
IRQ_disableAll();
IRQ_setVecs((Uint32)&VECSTART);
IRQ_plug (RTC_EVENT, &rtc_isr);
IRQ_enable(RTC_EVENT);
IRQ_globalEnable();
// before writing the time to RTC Registers clear time update bit
*RTCUPDATE = 0;
// set time registers
*RTCMIL = 0;
*RTCSEC = 0;
*RTCMIN = 0;
*RTCHOUR = 0;
*RTCDAY = 0;
*RTCMONTH = 0;
*RTCYEAR = 0;
// Time updates enabled
*RTCUPDATE |= 0x8000;
while( (*RTCUPDATE & 0x8000) && (--timeOut != 0));
// set interrupt register
*RTCINTREG = 0x0002;
// enable interrupts
*RTCINTEN = 0x0001;
}
void main(void)
{
Uint16 i;
// disable idle on all domains
*ICR = 0x000E;
asm(" idle");
asm(" nop");
asm(" nop");
asm(" nop");
// Configure PLL
configure_pll();
*PCGCR1 &= 0x7FFF;
*PCGCR2 &= 0x007F;
// Idle Setup
// Reset peripherals
*PSRCR = 0x0020;
*PRCR = 0x00BF;
for(i=0; i<0xff; i++)
{
asm(" nop");
}
// We need to active the EMIF clock so it can ACK our request
// Activate EMIF Clock
// Proably should activate USB and UART's clocks also, but that seems
// to be done by bootloader
*PCGCR1 = 0x0000;
*PCGCR2 = 0x0000;
// Configure IO for toggling
configure_io_toogle();
// configure RTC Second Alarm
configure_rtc();
// disable TMR0
*TCR0 = 0;
// disable USB OSC
*USBSCR = 0x804C;
// Need to request from UART / USB / EMIF if we can disable clocks
*CLKSTOP = 0x0015;
// need to check to make sure all of the above ack before disabling clocks
while(0x3F != *CLKSTOP)
{
asm(" nop");
}
// Disable all clocks but SYSCLK
*PCGCR2 = 0x007F;
*PCGCR1 = 0x7FFF;
while(1)
{
// wait for ISR to fire
bPllBypass = 1;
// Disable & Powerdown the PLL
*CCR2 = 0x0000;
*CGCR1 &= 0xEFFF;
// Configure for Idle, enable idle on all domains
*ICR = 0x03EF; // enable idle on all domains
asm(" nop");
asm(" nop");
asm(" idle");
asm(" nop");
asm(" nop");
toggle_io();
}
}