fixed coding conventions (mostly by astyle)

This commit is contained in:
Oliver Hahm 2013-06-21 03:52:57 +02:00
parent ffeb6f8523
commit 5d70656343
50 changed files with 2513 additions and 2109 deletions

View File

@ -26,42 +26,43 @@ Boston, MA 02111-1307, USA. */
static inline unsigned __get_cpsr(void) static inline unsigned __get_cpsr(void)
{ {
unsigned long retval; unsigned long retval;
asm volatile (" mrs %0, cpsr" : "=r" (retval) : /* no inputs */ ); asm volatile(" mrs %0, cpsr" : "=r"(retval) : /* no inputs */);
return retval; return retval;
} }
int inISR(void) int inISR(void)
{ {
int retval; int retval;
asm volatile (" mrs %0, cpsr" : "=r" (retval) : /* no inputs */ ); asm volatile(" mrs %0, cpsr" : "=r"(retval) : /* no inputs */);
return (retval & INTMode) == 18; return (retval & INTMode) == 18;
} }
static inline void __set_cpsr(unsigned val) static inline void __set_cpsr(unsigned val)
{ {
asm volatile (" msr cpsr, %0" : /* no outputs */ : "r" (val) ); asm volatile(" msr cpsr, %0" : /* no outputs */ : "r"(val));
} }
unsigned disableIRQ(void) unsigned disableIRQ(void)
{ {
unsigned _cpsr; unsigned _cpsr;
_cpsr = __get_cpsr(); _cpsr = __get_cpsr();
__set_cpsr(_cpsr | IRQ_MASK); __set_cpsr(_cpsr | IRQ_MASK);
return _cpsr; return _cpsr;
} }
unsigned restoreIRQ(unsigned oldCPSR) unsigned restoreIRQ(unsigned oldCPSR)
{ {
unsigned _cpsr; unsigned _cpsr;
_cpsr = __get_cpsr(); _cpsr = __get_cpsr();
__set_cpsr((_cpsr & ~IRQ_MASK) | (oldCPSR & IRQ_MASK)); __set_cpsr((_cpsr & ~IRQ_MASK) | (oldCPSR & IRQ_MASK));
return _cpsr; return _cpsr;
} }
unsigned IRQenabled(void) { unsigned IRQenabled(void)
{
unsigned _cpsr; unsigned _cpsr;
_cpsr = __get_cpsr(); _cpsr = __get_cpsr();
@ -70,38 +71,38 @@ unsigned IRQenabled(void) {
unsigned enableIRQ(void) unsigned enableIRQ(void)
{ {
unsigned _cpsr; unsigned _cpsr;
_cpsr = __get_cpsr(); _cpsr = __get_cpsr();
__set_cpsr(_cpsr & ~IRQ_MASK); __set_cpsr(_cpsr & ~IRQ_MASK);
return _cpsr; return _cpsr;
} }
unsigned disableFIQ(void) unsigned disableFIQ(void)
{ {
unsigned _cpsr; unsigned _cpsr;
_cpsr = __get_cpsr(); _cpsr = __get_cpsr();
__set_cpsr(_cpsr | FIQ_MASK); __set_cpsr(_cpsr | FIQ_MASK);
return _cpsr; return _cpsr;
} }
unsigned restoreFIQ(unsigned oldCPSR) unsigned restoreFIQ(unsigned oldCPSR)
{ {
unsigned _cpsr; unsigned _cpsr;
_cpsr = __get_cpsr(); _cpsr = __get_cpsr();
__set_cpsr((_cpsr & ~FIQ_MASK) | (oldCPSR & FIQ_MASK)); __set_cpsr((_cpsr & ~FIQ_MASK) | (oldCPSR & FIQ_MASK));
return _cpsr; return _cpsr;
} }
unsigned enableFIQ(void) unsigned enableFIQ(void)
{ {
unsigned _cpsr; unsigned _cpsr;
_cpsr = __get_cpsr(); _cpsr = __get_cpsr();
__set_cpsr(_cpsr & ~FIQ_MASK); __set_cpsr(_cpsr & ~FIQ_MASK);
return _cpsr; return _cpsr;
} }

View File

@ -41,7 +41,7 @@ void thread_yield(void)
char *thread_stack_init(void *task_func, void *stack_start, int stack_size) char *thread_stack_init(void *task_func, void *stack_start, int stack_size)
{ {
unsigned int *stk; unsigned int *stk;
stk = (unsigned int *) (stack_start + stack_size); stk = (unsigned int *)(stack_start + stack_size);
stk--; stk--;
*stk = STACK_MARKER; *stk = STACK_MARKER;
@ -52,10 +52,10 @@ char *thread_stack_init(void *task_func, void *stack_start, int stack_size)
/* set the stack pointer (SP) */ /* set the stack pointer (SP) */
stk--; stk--;
*stk = (unsigned int) (stack_start + stack_size) - 4; *stk = (unsigned int)(stack_start + stack_size) - 4;
/* build base stack */ /* build base stack */
for (int i = REGISTER_CNT; i>= 0 ; i--) { for(int i = REGISTER_CNT; i >= 0 ; i--) {
stk--; stk--;
*stk = i; *stk = i;
} }
@ -67,32 +67,35 @@ char *thread_stack_init(void *task_func, void *stack_start, int stack_size)
stk--; stk--;
*stk = (unsigned int) NEW_TASK_CPSR; *stk = (unsigned int) NEW_TASK_CPSR;
return (char*) stk; return (char *)stk;
} }
void thread_print_stack(void) void thread_print_stack(void)
{ {
register void *stack = 0; register void *stack = 0;
asm( "mov %0, sp" : "=r" (stack)); asm("mov %0, sp" : "=r"(stack));
register unsigned int *s = (unsigned int*) stack; register unsigned int *s = (unsigned int *)stack;
printf("task: %X SP: %X\n", (unsigned int) active_thread, (unsigned int) stack); printf("task: %X SP: %X\n", (unsigned int) active_thread, (unsigned int) stack);
register int i = 0; register int i = 0;
s += 5; s += 5;
while (*s != STACK_MARKER) {
while(*s != STACK_MARKER) {
printf("STACK (%u) addr=%X = %X \n", i, (unsigned int) s, (unsigned int) *s); printf("STACK (%u) addr=%X = %X \n", i, (unsigned int) s, (unsigned int) *s);
s++; s++;
i++; i++;
} }
printf("STACK (%u)= %X \n",i,*s);
printf("STACK (%u)= %X \n", i, *s);
} }
__attribute__((naked,noreturn)) void arm_reset(void) __attribute__((naked, noreturn)) void arm_reset(void)
{ {
dINT(); dINT();
WDTC = 0x00FFF; WDTC = 0x00FFF;
WDMOD = 0x03; WDMOD = 0x03;
WDFEED= 0xAA; WDFEED = 0xAA;
WDFEED= 0x55; WDFEED = 0x55;
while(1); while(1);
} }

View File

@ -48,58 +48,67 @@ and the mailinglist (subscription via web site)
#include <kernel.h> #include <kernel.h>
#include <thread.h> #include <thread.h>
void FIQ_Routine (void) __attribute__ ((interrupt("FIQ"))); void FIQ_Routine(void) __attribute__((interrupt("FIQ")));
//void SWI_Routine (void) __attribute__ ((interrupt("SWI"))); //void SWI_Routine (void) __attribute__ ((interrupt("SWI")));
void UNDEF_Routine (void) __attribute__ ((interrupt("UNDEF"))); void UNDEF_Routine(void) __attribute__((interrupt("UNDEF")));
void IRQ_Routine (void) { void IRQ_Routine(void)
{
printf("Kernel Panic,\nEarly IRQ call\n"); printf("Kernel Panic,\nEarly IRQ call\n");
while(1){};
while(1) {};
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void FIQ_Routine (void) { void FIQ_Routine(void)
{
printf("Kernel Panic,\nEarly FIQ call\n"); printf("Kernel Panic,\nEarly FIQ call\n");
while(1){};
while(1) {};
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SWI_Routine (void) { void SWI_Routine(void)
{
printf("Kernel Panic,\nEarly SWI call\n"); printf("Kernel Panic,\nEarly SWI call\n");
while(1){};
while(1) {};
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void DEBUG_Routine (void) { void DEBUG_Routine(void)
{
printf("DEBUG hit."); printf("DEBUG hit.");
while(1){};
while(1) {};
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
volatile int arm_abortflag = 0; volatile int arm_abortflag = 0;
void abtorigin(const char* vector, u_long* lnk_ptr1) void abtorigin(const char *vector, u_long *lnk_ptr1)
{ {
register u_long* lnk_ptr2; register u_long *lnk_ptr2;
register unsigned long* sp; register unsigned long *sp;
register unsigned int cpsr, spsr; register unsigned int cpsr, spsr;
__asm__ __volatile__("mrs %0, cpsr" : "=r" (cpsr) ); // copy current mode __asm__ __volatile__("mrs %0, cpsr" : "=r"(cpsr)); // copy current mode
__asm__ __volatile__("mrs %0, spsr" : "=r" (spsr) ); // copy dabt generating mode __asm__ __volatile__("mrs %0, spsr" : "=r"(spsr)); // copy dabt generating mode
__asm__ __volatile__("msr cpsr_c, %0" :: "r" (spsr) ); // switch to dabt generating mode __asm__ __volatile__("msr cpsr_c, %0" :: "r"(spsr)); // switch to dabt generating mode
__asm__ __volatile__("mov %0, lr" : "=r" (lnk_ptr2)); // copy lr __asm__ __volatile__("mov %0, lr" : "=r"(lnk_ptr2)); // copy lr
__asm__ __volatile__("mov %0, sp" : "=r" (sp)); // copy sp __asm__ __volatile__("mov %0, sp" : "=r"(sp)); // copy sp
__asm__ __volatile__("msr cpsr_c, %0" :: "r" (cpsr) ); // switch back to abt mode __asm__ __volatile__("msr cpsr_c, %0" :: "r"(cpsr)); // switch back to abt mode
printf("#! %s abort at %p (0x%08lX) originating from %p (0x%08lX) in mode 0x%X\n", printf("#! %s abort at %p (0x%08lX) originating from %p (0x%08lX) in mode 0x%X\n",
vector, (void*)lnk_ptr1, *(lnk_ptr1), (void*)lnk_ptr2, *(lnk_ptr2), spsr vector, (void *)lnk_ptr1, *(lnk_ptr1), (void *)lnk_ptr2, *(lnk_ptr2), spsr
); );
stdio_flush(); stdio_flush();
exit(1); exit(1);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void UNDEF_Routine (void) { void UNDEF_Routine(void)
register u_long* lnk_ptr; {
__asm__ __volatile__("sub %0, lr, #8" : "=r" (lnk_ptr) ); // get aborting instruction register u_long *lnk_ptr;
__asm__ __volatile__("sub %0, lr, #8" : "=r"(lnk_ptr)); // get aborting instruction
if( arm_abortflag == 0 ) { if(arm_abortflag == 0) {
arm_abortflag = 1; // remember state (if printing should fail again) arm_abortflag = 1; // remember state (if printing should fail again)
abtorigin("undef", lnk_ptr); abtorigin("undef", lnk_ptr);
} }
@ -107,11 +116,12 @@ void UNDEF_Routine (void) {
exit(1); exit(1);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void PABT_Routine (void) { void PABT_Routine(void)
register u_long* lnk_ptr; {
__asm__ __volatile__("sub %0, lr, #8" : "=r" (lnk_ptr) ); // get aborting instruction register u_long *lnk_ptr;
__asm__ __volatile__("sub %0, lr, #8" : "=r"(lnk_ptr)); // get aborting instruction
if( arm_abortflag == 0 ) { if(arm_abortflag == 0) {
arm_abortflag = 1; // remember state (if printing should fail again) arm_abortflag = 1; // remember state (if printing should fail again)
abtorigin("pabt", lnk_ptr); abtorigin("pabt", lnk_ptr);
} }
@ -119,11 +129,12 @@ void PABT_Routine (void) {
exit(1); exit(1);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void DABT_Routine (void) { void DABT_Routine(void)
register u_long* lnk_ptr; {
__asm__ __volatile__("sub %0, lr, #8" : "=r" (lnk_ptr) ); // get aborting instruction register u_long *lnk_ptr;
__asm__ __volatile__("sub %0, lr, #8" : "=r"(lnk_ptr)); // get aborting instruction
if( arm_abortflag == 0 ) { if(arm_abortflag == 0) {
arm_abortflag = 1; // remember state (if printing should fail again) arm_abortflag = 1; // remember state (if printing should fail again)
abtorigin("data", lnk_ptr); abtorigin("data", lnk_ptr);
} }
@ -140,27 +151,32 @@ bl_init_data(void)
extern unsigned int __bss_start; extern unsigned int __bss_start;
extern unsigned int __bss_end; extern unsigned int __bss_end;
register unsigned int* p1; register unsigned int *p1;
register unsigned int* p2; register unsigned int *p2;
register unsigned int* p3; register unsigned int *p3;
// initialize data from flash // initialize data from flash
// (linker script ensures that data is 32-bit aligned) // (linker script ensures that data is 32-bit aligned)
p1 = &_etext; p1 = &_etext;
p2 = &_data; p2 = &_data;
p3 = &_edata; p3 = &_edata;
while( p2 < p3 )
while(p2 < p3) {
*p2++ = *p1++; *p2++ = *p1++;
}
// clear bss // clear bss
// (linker script ensures that bss is 32-bit aligned) // (linker script ensures that bss is 32-bit aligned)
p1 = &__bss_start; p1 = &__bss_start;
p2 = &__bss_end; p2 = &__bss_end;
while( p1 < p2 )
while(p1 < p2) {
*p1++ = 0; *p1++ = 0;
}
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void bootloader(void) { void bootloader(void)
{
extern void bl_uart_init(void); extern void bl_uart_init(void);
extern void bl_init_ports(void); extern void bl_init_ports(void);
extern void bl_init_clks(void); extern void bl_init_clks(void);

View File

@ -5,8 +5,10 @@
* @brief ARM kernel timer CPU dependent functions implementation * @brief ARM kernel timer CPU dependent functions implementation
* *
* @author Freie Universität Berlin, Computer Systems & Telematics * @author Freie Universität Berlin, Computer Systems & Telematics
* @author INRIA
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de> * @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
* @author Heiko Will <hwill@inf.fu-berlin.de> * @author Heiko Will <hwill@inf.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* *
*/ */
@ -18,87 +20,98 @@
#define VULP(x) ((volatile unsigned long*) (x)) #define VULP(x) ((volatile unsigned long*) (x))
/// High level interrupt handler /*/ High level interrupt handler */
static void (*int_handler)(int); static void (*int_handler)(int);
/// Timer 0-3 interrupt handler /*/ Timer 0-3 interrupt handler */
static void timer_irq(void) __attribute__((interrupt("IRQ"))); static void timer_irq(void) __attribute__((interrupt("IRQ")));
inline static unsigned long get_base_address(short timer) { inline static unsigned long get_base_address(short timer)
return (volatile unsigned long)(TMR0_BASE_ADDR + (timer / 8) * 0x6C000 + (timer/4 - (timer/8)*2) * 0x4000); {
return (volatile unsigned long)(TMR0_BASE_ADDR + (timer / 8) * 0x6C000 + (timer / 4 - (timer / 8) * 2) * 0x4000);
} }
static void timer_irq(void) static void timer_irq(void)
{ {
short timer = 0; short timer = 0;
if (T0IR) {
if(T0IR) {
timer = 0; timer = 0;
} else if (T1IR) { }
else if(T1IR) {
timer = 4; timer = 4;
} else if (T2IR) { }
else if(T2IR) {
timer = 8; timer = 8;
} }
volatile unsigned long base = get_base_address(timer); volatile unsigned long base = get_base_address(timer);
if (*VULP(base+TXIR) & BIT0) { if(*VULP(base + TXIR) & BIT0) {
*VULP(base+TXMCR) &= ~BIT0; *VULP(base + TXMCR) &= ~BIT0;
*VULP(base+TXIR) = BIT0; *VULP(base + TXIR) = BIT0;
int_handler(timer); int_handler(timer);
} }
if (*VULP(base+TXIR) & BIT1) {
*VULP(base+TXMCR) &= ~BIT3; if(*VULP(base + TXIR) & BIT1) {
*VULP(base+TXIR) = BIT1; *VULP(base + TXMCR) &= ~BIT3;
*VULP(base + TXIR) = BIT1;
int_handler(timer + 1); int_handler(timer + 1);
} }
if (*VULP(base+TXIR) & BIT2) {
*VULP(base+TXMCR) &= ~BIT6; if(*VULP(base + TXIR) & BIT2) {
*VULP(base+TXIR) = BIT2; *VULP(base + TXMCR) &= ~BIT6;
*VULP(base + TXIR) = BIT2;
int_handler(timer + 2); int_handler(timer + 2);
} }
if (*VULP(base+TXIR) & BIT3) {
*VULP(base+TXMCR) &= ~BIT9; if(*VULP(base + TXIR) & BIT3) {
*VULP(base+TXIR) = BIT3; *VULP(base + TXMCR) &= ~BIT9;
*VULP(base + TXIR) = BIT3;
int_handler(timer + 3); int_handler(timer + 3);
} }
VICVectAddr = 0; // acknowledge interrupt (if using VIC IRQ) VICVectAddr = 0; /* acknowledge interrupt (if using VIC IRQ) */
} }
static void timer0_init(uint32_t cpsr) { static void timer0_init(uint32_t cpsr)
PCONP |= PCTIM0; // power up timer {
T0TCR = 2; // disable and reset timer PCONP |= PCTIM0; /* power up timer */
T0MCR = 0; // disable compare T0TCR = 2; /* disable and reset timer */
T0CCR = 0; // capture is disabled T0MCR = 0; /* disable compare */
T0EMR = 0; // no external match output T0CCR = 0; /* capture is disabled */
T0PR = cpsr; // set prescaler T0EMR = 0; /* no external match output */
T0PR = cpsr; /* set prescaler */
install_irq(TIMER0_INT, &timer_irq, 1); install_irq(TIMER0_INT, &timer_irq, 1);
T0TCR = 1; // reset counter T0TCR = 1; /* reset counter */
} }
static void timer1_init(uint32_t cpsr) { static void timer1_init(uint32_t cpsr)
PCONP |= PCTIM1; // power up timer {
T1TCR = 2; // disable and reset timer PCONP |= PCTIM1; /* power up timer */
T1MCR = 0; // disable compare T1TCR = 2; /* disable and reset timer */
T1CCR = 0; // capture is disabled T1MCR = 0; /* disable compare */
T1EMR = 0; // no external match output T1CCR = 0; /* capture is disabled */
T1PR = cpsr; // set prescaler T1EMR = 0; /* no external match output */
T1PR = cpsr; /* set prescaler */
install_irq(TIMER1_INT, &timer_irq, 1); install_irq(TIMER1_INT, &timer_irq, 1);
T1TCR = 1; // reset counter T1TCR = 1; /* reset counter */
} }
static void timer2_init(uint32_t cpsr) { static void timer2_init(uint32_t cpsr)
PCONP |= PCTIM2; // power up timer {
T2TCR = 2; // disable and reset timer PCONP |= PCTIM2; /* power up timer */
T2MCR = 0; // disable compare T2TCR = 2; /* disable and reset timer */
T2CCR = 0; // capture is disabled T2MCR = 0; /* disable compare */
T2EMR = 0; // no external match output T2CCR = 0; /* capture is disabled */
T2PR = cpsr; // set prescaler T2EMR = 0; /* no external match output */
T2PR = cpsr; /* set prescaler */
install_irq(TIMER2_INT, &timer_irq, 1); install_irq(TIMER2_INT, &timer_irq, 1);
T2TCR = 1; // reset counter T2TCR = 1; /* reset counter */
} }
void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu) { void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu)
{
uint32_t cpsr; uint32_t cpsr;
int_handler = handler; int_handler = handler;
cpu_clock_scale(fcpu, HWTIMER_SPEED, &cpsr); cpu_clock_scale(fcpu, HWTIMER_SPEED, &cpsr);
@ -109,7 +122,8 @@ void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu) {
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void hwtimer_arch_enable_interrupt(void) { void hwtimer_arch_enable_interrupt(void)
{
VICIntEnable = 1 << TIMER0_INT; /* Enable Interrupt */ VICIntEnable = 1 << TIMER0_INT; /* Enable Interrupt */
VICIntEnable = 1 << TIMER1_INT; /* Enable Interrupt */ VICIntEnable = 1 << TIMER1_INT; /* Enable Interrupt */
VICIntEnable = 1 << TIMER2_INT; /* Enable Interrupt */ VICIntEnable = 1 << TIMER2_INT; /* Enable Interrupt */
@ -117,7 +131,8 @@ void hwtimer_arch_enable_interrupt(void) {
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void hwtimer_arch_disable_interrupt(void) { void hwtimer_arch_disable_interrupt(void)
{
VICIntEnClr = 1 << TIMER0_INT; /* Disable Interrupt */ VICIntEnClr = 1 << TIMER0_INT; /* Disable Interrupt */
VICIntEnClr = 1 << TIMER1_INT; /* Disable Interrupt */ VICIntEnClr = 1 << TIMER1_INT; /* Disable Interrupt */
VICIntEnClr = 1 << TIMER2_INT; /* Disable Interrupt */ VICIntEnClr = 1 << TIMER2_INT; /* Disable Interrupt */
@ -125,56 +140,61 @@ void hwtimer_arch_disable_interrupt(void) {
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void hwtimer_arch_set(unsigned long offset, short timer) { void hwtimer_arch_set(unsigned long offset, short timer)
// Calculate base address of timer register {
// Timer 0-3 are matched to TIMER0 /* Calculate base address of timer register */
// Timer 4-7 are matched to TIMER1 /* Timer 0-3 are matched to TIMER0 */
// Timer 8-11 are matched to TIMER2 /* Timer 4-7 are matched to TIMER1 */
/* Timer 8-11 are matched to TIMER2 */
volatile unsigned long base = get_base_address(timer); volatile unsigned long base = get_base_address(timer);
// Calculate match register address of corresponding timer /* Calculate match register address of corresponding timer */
timer %= 4; timer %= 4;
unsigned long cpsr = disableIRQ(); unsigned long cpsr = disableIRQ();
volatile unsigned long* addr = VULP(base + TXMR0 + 4 * timer); volatile unsigned long *addr = VULP(base + TXMR0 + 4 * timer);
// Calculate match register value /* Calculate match register value */
unsigned long value = *VULP(base + TXTC) + offset; unsigned long value = *VULP(base + TXTC) + offset;
*addr = value; // set match register *addr = value; /* set match register */
*VULP(base+TXIR) = 0x01 << timer; // reset interrupt register value for corresponding match register *VULP(base + TXIR) = 0x01 << timer; /* reset interrupt register value for corresponding match register */
*VULP(base+TXMCR) &= ~(7 << (3 * timer)); // Clear all bits *VULP(base + TXMCR) &= ~(7 << (3 * timer)); /* Clear all bits */
*VULP(base+TXMCR) |= (MR0I << (3 * timer)); // enable interrupt for match register *VULP(base + TXMCR) |= (MR0I << (3 * timer)); /* enable interrupt for match register */
restoreIRQ(cpsr); restoreIRQ(cpsr);
} }
void hwtimer_arch_set_absolute(unsigned long value, short timer) { void hwtimer_arch_set_absolute(unsigned long value, short timer)
// Calculate base address of timer register {
// Timer 0-3 are matched to TIMER0 /* Calculate base address of timer register */
// Timer 4-7 are matched to TIMER1 /* Timer 0-3 are matched to TIMER0 */
// Timer 8-11 are matched to TIMER2 /* Timer 4-7 are matched to TIMER1 */
/* Timer 8-11 are matched to TIMER2 */
volatile unsigned long base = get_base_address(timer); volatile unsigned long base = get_base_address(timer);
// Calculate match register address of corresponding timer /* Calculate match register address of corresponding timer */
timer %= 4; timer %= 4;
volatile unsigned long* addr = VULP(base + TXMR0 + 4 * timer); volatile unsigned long *addr = VULP(base + TXMR0 + 4 * timer);
// Calculate match register value /* Calculate match register value */
*addr = value; // set match register *addr = value; /* set match register */
*VULP(base+TXIR) = 0x01 << timer; // reset interrupt register value for corresponding match register *VULP(base + TXIR) = 0x01 << timer; /* reset interrupt register value for corresponding match register */
*VULP(base+TXMCR) &= ~(7 << (3 * timer)); // Clear all bits *VULP(base + TXMCR) &= ~(7 << (3 * timer)); /* Clear all bits */
*VULP(base+TXMCR) |= (MR0I << (3 * timer)); // enable interrupt for match register *VULP(base + TXMCR) |= (MR0I << (3 * timer)); /* enable interrupt for match register */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void hwtimer_arch_unset(short timer) { void hwtimer_arch_unset(short timer)
{
volatile unsigned long base = get_base_address(timer); volatile unsigned long base = get_base_address(timer);
timer %= 4; timer %= 4;
*VULP(base+TXMCR) &= ~(MR0I << (3 * timer)); // disable interrupt for match register *VULP(base + TXMCR) &= ~(MR0I << (3 * timer)); /* disable interrupt for match register */
*VULP(base+TXIR) = 0x01 << timer; // reset interrupt register value for corresponding match register *VULP(base + TXIR) = 0x01 << timer; /* reset interrupt register value for corresponding match register */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
unsigned long hwtimer_arch_now(void) { unsigned long hwtimer_arch_now(void)
{
return T0TC; return T0TC;
} }
void hwtimer_arch_setcounter(unsigned int val) { void hwtimer_arch_setcounter(unsigned int val)
{
T0TC = val; T0TC = val;
} }

View File

@ -1,7 +1,6 @@
/* iap driver /* iap driver
* *
* based on iap driver for LPC2148 Controller made by Andreas Weschenfelder, 2008 * based on iap driver for LPC2148 Controller made by Andreas Weschenfelder, 2008
* see:
* *
*/ */
@ -14,11 +13,11 @@
#include <debug.h> #include <debug.h>
/* pointer to reserved flash rom section for configuration data */ /* pointer to reserved flash rom section for configuration data */
__attribute ((aligned(256))) char configmem[256] __attribute__ ((section (".configmem"))); __attribute((aligned(256))) char configmem[256] __attribute__((section(".configmem")));
static unsigned int iap_command[5]; // contains parameters for IAP command static unsigned int iap_command[5]; // contains parameters for IAP command
static unsigned int iap_result[2]; // contains results static unsigned int iap_result[2]; // contains results
typedef void (*IAP) (unsigned int[],unsigned int[]); // typedefinition for IAP entry function typedef void (*IAP)(unsigned int[], unsigned int[]); // typedefinition for IAP entry function
IAP IAP_Entry; IAP IAP_Entry;
/* some function prototypes */ /* some function prototypes */
@ -32,100 +31,101 @@ static uint32_t iap(uint32_t code, uint32_t p1, uint32_t p2, uint32_t p3, uint32
/****************************************************************************** /******************************************************************************
* P U B L I C F U N C T I O N S * P U B L I C F U N C T I O N S
*****************************************************************************/ *****************************************************************************/
uint8_t flashrom_write(uint8_t *dst, char *src, size_t size) { uint8_t flashrom_write(uint8_t *dst, char *src, size_t size)
char err; {
unsigned intstate; char err;
uint8_t sec; unsigned intstate;
uint8_t sec;
//buffer_vic = VICIntEnable; // save interrupt enable sec = iap_get_sector((uint32_t) dst);
//VICIntEnClr = 0xFFFFFFFF; // clear vic
sec = iap_get_sector((uint32_t) dst); if(sec == INVALID_ADDRESS) {
if (sec == INVALID_ADDRESS) {
DEBUG("Invalid address\n"); DEBUG("Invalid address\n");
return 0; return 0;
} }
/* check sector */ /* check sector */
if(blank_check_sector(sec, sec) == SECTOR_NOT_BLANK) { if(blank_check_sector(sec, sec) == SECTOR_NOT_BLANK) {
DEBUG("Warning: Sector %i not blank\n", sec); DEBUG("Warning: Sector %i not blank\n", sec);
} }
/* prepare sector */ /* prepare sector */
err = prepare_sectors(sec, sec); err = prepare_sectors(sec, sec);
if (err) {
DEBUG("\n-- ERROR: PREPARE_SECTOR_FOR_WRITE_OPERATION: %u\n", err); if(err) {
/* set interrupts back and return */ DEBUG("\n-- ERROR: PREPARE_SECTOR_FOR_WRITE_OPERATION: %u\n", err);
// VICIntEnable = buffer_vic; return 0;
return 0; }
}
/* write flash */ /* write flash */
else { else {
intstate = disableIRQ(); intstate = disableIRQ();
err = copy_ram_to_flash((uint32_t) dst, (uint32_t) src, 256); err = copy_ram_to_flash((uint32_t) dst, (uint32_t) src, 256);
restoreIRQ(intstate); restoreIRQ(intstate);
if(err) {
DEBUG("ERROR: COPY_RAM_TO_FLASH: %u\n", err); if(err) {
DEBUG("ERROR: COPY_RAM_TO_FLASH: %u\n", err);
/* set interrupts back and return */ /* set interrupts back and return */
restoreIRQ(intstate); restoreIRQ(intstate);
// VICIntEnable = buffer_vic; return 0;
return 0; }
}
/* check result */ /* check result */
else { else {
err = compare((uint32_t) dst, (uint32_t) src, 256); err = compare((uint32_t) dst, (uint32_t) src, 256);
if (err) {
DEBUG("ERROR: COMPARE: %i (at position %u)\n", err, iap_result[1]); if(err) {
/* set interrupts back and return */ DEBUG("ERROR: COMPARE: %i (at position %u)\n", err, iap_result[1]);
// VICIntEnable = buffer_vic; return 0;
return 0; }
} else {
else DEBUG("Data successfully written!\n");
{ return 1;
DEBUG("Data successfully written!\n"); }
/* set interrupts back and return */ }
// VICIntEnable = buffer_vic; }
return 1;
}
}
}
} }
uint8_t flashrom_erase(uint8_t *addr) { uint8_t flashrom_erase(uint8_t *addr)
{
uint8_t sec = iap_get_sector((uint32_t) addr); uint8_t sec = iap_get_sector((uint32_t) addr);
unsigned intstate; unsigned intstate;
if (sec == INVALID_ADDRESS) { if(sec == INVALID_ADDRESS) {
DEBUG("Invalid address\n"); DEBUG("Invalid address\n");
return 0; return 0;
} }
/* check sector */ /* check sector */
if (!blank_check_sector(sec, sec)) { if(!blank_check_sector(sec, sec)) {
DEBUG("Sector already blank!\n"); DEBUG("Sector already blank!\n");
return 1; return 1;
} }
/* prepare sector */
if (prepare_sectors(sec, sec)) { /* prepare sector */
DEBUG("-- ERROR: PREPARE_SECTOR_FOR_WRITE_OPERATION --\n"); if(prepare_sectors(sec, sec)) {
return 0; DEBUG("-- ERROR: PREPARE_SECTOR_FOR_WRITE_OPERATION --\n");
} return 0;
}
intstate = disableIRQ(); intstate = disableIRQ();
/* erase sector */ /* erase sector */
if (erase_sectors(sec, sec)) { if(erase_sectors(sec, sec)) {
DEBUG("-- ERROR: ERASE SECTOR --\n"); DEBUG("-- ERROR: ERASE SECTOR --\n");
restoreIRQ(intstate); restoreIRQ(intstate);
return 0; return 0;
} }
restoreIRQ(intstate); restoreIRQ(intstate);
/* check again */ /* check again */
if (blank_check_sector(sec, sec)) { if(blank_check_sector(sec, sec)) {
DEBUG("-- ERROR: BLANK_CHECK_SECTOR\n"); DEBUG("-- ERROR: BLANK_CHECK_SECTOR\n");
return 0; return 0;
} }
DEBUG("Sector successfully erased.\n");
return 1; DEBUG("Sector successfully erased.\n");
return 1;
} }
@ -133,15 +133,16 @@ uint8_t flashrom_erase(uint8_t *addr) {
* PRIVATE FUNCTIONS * PRIVATE FUNCTIONS
*****************************************************************************/ *****************************************************************************/
static uint32_t iap(uint32_t code, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) { static uint32_t iap(uint32_t code, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4)
iap_command[0] = code; // set command code {
iap_command[1] = p1; // set 1st param iap_command[0] = code; // set command code
iap_command[2] = p2; // set 2nd param iap_command[1] = p1; // set 1st param
iap_command[3] = p3; // set 3rd param iap_command[2] = p2; // set 2nd param
iap_command[4] = p4; // set 4th param iap_command[3] = p3; // set 3rd param
iap_command[4] = p4; // set 4th param
((void (*)())0x7ffffff1)(iap_command, iap_result); // IAP entry point ((void (*)())0x7ffffff1)(iap_command, iap_result); // IAP entry point
return *iap_result; return *iap_result;
} }
/****************************************************************************** /******************************************************************************
@ -165,8 +166,9 @@ static uint32_t iap(uint32_t code, uint32_t p1, uint32_t p2, uint32_t p3, uint32
* Result0: Offset of the first non blank word location if the status code is SECTOR_NOT_BLANK. * Result0: Offset of the first non blank word location if the status code is SECTOR_NOT_BLANK.
* Result1: Contents of non blank wird location. * Result1: Contents of non blank wird location.
*****************************************************************************/ *****************************************************************************/
uint32_t blank_check_sector(uint32_t tmp_sect1, uint32_t tmp_sect2) { uint32_t blank_check_sector(uint32_t tmp_sect1, uint32_t tmp_sect2)
return iap(BLANK_CHECK_SECTOR, tmp_sect1, tmp_sect2, 0 , 0); {
return iap(BLANK_CHECK_SECTOR, tmp_sect1, tmp_sect2, 0 , 0);
} }
@ -197,8 +199,9 @@ uint32_t blank_check_sector(uint32_t tmp_sect1, uint32_t tmp_sect2) {
* SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION | * SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION |
* BUSY * BUSY
*****************************************************************************/ *****************************************************************************/
uint32_t copy_ram_to_flash(uint32_t tmp_adr_dst, uint32_t tmp_adr_src, uint32_t tmp_size) { uint32_t copy_ram_to_flash(uint32_t tmp_adr_dst, uint32_t tmp_adr_src, uint32_t tmp_size)
return iap(COPY_RAM_TO_FLASH, tmp_adr_dst, tmp_adr_src, tmp_size, _XTAL); {
return iap(COPY_RAM_TO_FLASH, tmp_adr_dst, tmp_adr_src, tmp_size, _XTAL);
} }
@ -220,8 +223,9 @@ uint32_t copy_ram_to_flash(uint32_t tmp_adr_dst, uint32_t tmp_adr_src, uint32_t
* BUSY | * BUSY |
* INVALID_SECTOR * INVALID_SECTOR
*****************************************************************************/ *****************************************************************************/
uint32_t prepare_sectors(uint32_t tmp_sect1, uint32_t tmp_sect2) { uint32_t prepare_sectors(uint32_t tmp_sect1, uint32_t tmp_sect2)
return iap(PREPARE_SECTOR_FOR_WRITE_OPERATION, tmp_sect1, tmp_sect2, 0 , 0); {
return iap(PREPARE_SECTOR_FOR_WRITE_OPERATION, tmp_sect1, tmp_sect2, 0 , 0);
} }
@ -244,8 +248,9 @@ uint32_t prepare_sectors(uint32_t tmp_sect1, uint32_t tmp_sect2) {
* SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION | * SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION |
* INVALID_SECTOR * INVALID_SECTOR
*****************************************************************************/ *****************************************************************************/
uint32_t erase_sectors(uint32_t tmp_sect1, uint32_t tmp_sect2) { uint32_t erase_sectors(uint32_t tmp_sect1, uint32_t tmp_sect2)
return iap(ERASE_SECTOR, tmp_sect1, tmp_sect2, _XTAL, 0); {
return iap(ERASE_SECTOR, tmp_sect1, tmp_sect2, _XTAL, 0);
} }
@ -273,6 +278,7 @@ uint32_t erase_sectors(uint32_t tmp_sect1, uint32_t tmp_sect2) {
* ADDR_NOT_MAPPED * ADDR_NOT_MAPPED
* Result0: Offset of the first mismatch if the Status Code is COMPARE_ERROR. * Result0: Offset of the first mismatch if the Status Code is COMPARE_ERROR.
*****************************************************************************/ *****************************************************************************/
uint32_t compare(uint32_t tmp_adr_dst, uint32_t tmp_adr_src, uint32_t tmp_size) { uint32_t compare(uint32_t tmp_adr_dst, uint32_t tmp_adr_src, uint32_t tmp_size)
return iap(COMPARE, tmp_adr_dst, tmp_adr_src, tmp_size, 0); {
return iap(COMPARE, tmp_adr_dst, tmp_adr_src, tmp_size, 0);
} }

View File

@ -90,7 +90,7 @@ Boston, MA 02111-1307, USA. */
#include <stdbool.h> #include <stdbool.h>
#include "cpu.h" #include "cpu.h"
bool cpu_install_irq( int IntNumber, void *HandlerAddr, int Priority ); bool cpu_install_irq(int IntNumber, void *HandlerAddr, int Priority);
/** @} */ /** @} */
#endif /*ARMVIC_H_*/ #endif /*ARMVIC_H_*/

View File

@ -13,7 +13,7 @@ extern void eINT(void);
void thread_yield(void); void thread_yield(void);
uint32_t get_system_speed(void); uint32_t get_system_speed(void);
void cpu_clock_scale(uint32_t source, uint32_t target, uint32_t* prescale); void cpu_clock_scale(uint32_t source, uint32_t target, uint32_t *prescale);
void arm_reset(void); void arm_reset(void);
void stdio_flush(void); void stdio_flush(void);

View File

@ -23,15 +23,18 @@ static uint8_t function_pending = 0;
static uint16_t traced_functions = 0; static uint16_t traced_functions = 0;
static uint8_t profiling = 0; static uint8_t profiling = 0;
void __attribute__((__no_instrument_function__)) profiling_init(void) { void __attribute__((__no_instrument_function__)) profiling_init(void)
{
uint16_t i; uint16_t i;
for (i = 0; i < MAX_TRACED_FUNCTIONS; i++) {
for(i = 0; i < MAX_TRACED_FUNCTIONS; i++) {
functions[i].address = 0; functions[i].address = 0;
functions[i].time = 0; functions[i].time = 0;
functions[i].consumption = 0; functions[i].consumption = 0;
functions[i].counter = 0; functions[i].counter = 0;
} }
for (i = 0; i < PROFILING_STACK_SIZE; i++) {
for(i = 0; i < PROFILING_STACK_SIZE; i++) {
profiling_stack[i] = 0; profiling_stack[i] = 0;
} }
@ -40,33 +43,39 @@ void __attribute__((__no_instrument_function__)) profiling_init(void) {
profiling = 1; profiling = 1;
} }
static int16_t __attribute__((__no_instrument_function__)) get_function_index(uint32_t addr) { static int16_t __attribute__((__no_instrument_function__)) get_function_index(uint32_t addr)
{
uint16_t i; uint16_t i;
for (i = 0; i < MAX_TRACED_FUNCTIONS; i++) {
if (functions[i].address == addr) { for(i = 0; i < MAX_TRACED_FUNCTIONS; i++) {
if(functions[i].address == addr) {
return i; return i;
} }
} }
return -1; return -1;
} }
void __attribute__((__no_instrument_function__)) __cyg_profile_func_enter (void *func, void *caller) { void __attribute__((__no_instrument_function__)) __cyg_profile_func_enter(void *func, void *caller)
if (!profiling) { {
if(!profiling) {
return; return;
} }
int16_t idx = get_function_index((uint32_t) func); int16_t idx = get_function_index((uint32_t) func);
/* if function is not yet on traced */ /* if function is not yet on traced */
if ((idx < 0) && (traced_functions < MAX_TRACED_FUNCTIONS)) { if((idx < 0) && (traced_functions < MAX_TRACED_FUNCTIONS)) {
idx = traced_functions++; idx = traced_functions++;
functions[idx].address = (uint32_t) func; functions[idx].address = (uint32_t) func;
} }
/* maximu of traceable functions reached */ /* maximu of traceable functions reached */
else if (idx < 0) { else if(idx < 0) {
return; return;
} }
/* check if a profiled function is pending */ /* check if a profiled function is pending */
if (function_pending && (profiling_stack[profiling_sp] != idx)) { if(function_pending && (profiling_stack[profiling_sp] != idx)) {
functions[idx].time += T0TC - functions[idx].start_time; functions[idx].time += T0TC - functions[idx].start_time;
//functions[idx].consumption += ltc4150_get_intcount() - functions[idx].consumption_start; //functions[idx].consumption += ltc4150_get_intcount() - functions[idx].consumption_start;
functions[idx].consumption += ltc4150_get_total_mAh() - functions[idx].consumption_start; functions[idx].consumption += ltc4150_get_total_mAh() - functions[idx].consumption_start;
@ -83,32 +92,40 @@ void __attribute__((__no_instrument_function__)) __cyg_profile_func_enter (void
// functions[idx].consumption_start = ltc4150_get_intcount(); // functions[idx].consumption_start = ltc4150_get_intcount();
} }
void __attribute__((__no_instrument_function__)) __cyg_profile_func_exit (void *func, void *caller) { void __attribute__((__no_instrument_function__)) __cyg_profile_func_exit(void *func, void *caller)
if (!profiling) { {
if(!profiling) {
return; return;
} }
int16_t idx = get_function_index((uint32_t) func); int16_t idx = get_function_index((uint32_t) func);
if (idx >= 0) {
if(idx >= 0) {
functions[idx].time += T0TC - functions[idx].start_time; functions[idx].time += T0TC - functions[idx].start_time;
//functions[idx].consumption += ltc4150_get_intcount() - functions[idx].consumption_start; //functions[idx].consumption += ltc4150_get_intcount() - functions[idx].consumption_start;
functions[idx].consumption += ltc4150_get_total_mAh() - functions[idx].consumption_start; functions[idx].consumption += ltc4150_get_total_mAh() - functions[idx].consumption_start;
} }
/* reset pending flag */ /* reset pending flag */
function_pending = 0; function_pending = 0;
/* if another function is pending */ /* if another function is pending */
if (profiling_sp) { if(profiling_sp) {
if (--profiling_sp) { if(--profiling_sp) {
functions[profiling_stack[profiling_sp]].start_time = T0TC; functions[profiling_stack[profiling_sp]].start_time = T0TC;
functions[profiling_stack[profiling_sp]].consumption_start = ltc4150_get_total_mAh(); functions[profiling_stack[profiling_sp]].consumption_start = ltc4150_get_total_mAh();
} }
} }
} }
void profiling_stats(void) { void profiling_stats(void)
{
uint16_t i; uint16_t i;
for (i = 0; i < traced_functions; i++) {
// printf("Function @%04lX was running %u times for %lu ticks, consuming %li ltc-ticks\n", functions[i].address, functions[i].counter, functions[i].time, functions[i].consumption); for(i = 0; i < traced_functions; i++) {
printf("Function @%04lX was running %u times for %lu ticks, consuming %lf mAh\n", functions[i].address, functions[i].counter, functions[i].time, functions[i].consumption); // printf("Function @%04lX was running %u times for %lu ticks, consuming %li ltc-ticks\n", functions[i].address, functions[i].counter, functions[i].time, functions[i].consumption);
printf("Function @%04lX was running %u times for %lu ticks, consuming %lf mAh\n", functions[i].address, functions[i].counter, functions[i].time, functions[i].consumption);
} }
puts("________________________________________________________"); puts("________________________________________________________");
} }

View File

@ -74,13 +74,13 @@ extern uintptr_t __heap3_start; ///< start of heap memory space
extern uintptr_t __heap3_max; ///< maximum for end of heap memory space extern uintptr_t __heap3_max; ///< maximum for end of heap memory space
/// current position in heap /* current position in heap */
static caddr_t heap[NUM_HEAPS] = {(caddr_t)&__heap1_start,(caddr_t)&__heap3_start,(caddr_t)&__heap2_start}; // add heap3 before heap2 cause Heap3 address is lower then addr of heap2 static caddr_t heap[NUM_HEAPS] = {(caddr_t) &__heap1_start, (caddr_t) &__heap3_start, (caddr_t) &__heap2_start}; // add heap3 before heap2 cause Heap3 address is lower then addr of heap2
/// maximum position in heap /* maximum position in heap */
static const caddr_t heap_max[NUM_HEAPS] = {(caddr_t)&__heap1_max,(caddr_t)&__heap3_max,(caddr_t)&__heap2_max}; static const caddr_t heap_max[NUM_HEAPS] = {(caddr_t) &__heap1_max, (caddr_t) &__heap3_max, (caddr_t) &__heap2_max};
// start position in heap /* start position in heap */
static const caddr_t heap_start[NUM_HEAPS] = {(caddr_t)&__heap1_start,(caddr_t)&__heap3_start,(caddr_t)&__heap2_start}; static const caddr_t heap_start[NUM_HEAPS] = {(caddr_t) &__heap1_start, (caddr_t) &__heap3_start, (caddr_t) &__heap2_start};
// current heap in use /* current heap in use */
volatile static uint8_t iUsedHeap = 0; volatile static uint8_t iUsedHeap = 0;
/** @} */ /** @} */
@ -90,7 +90,7 @@ void heap_stats(void)
{ {
for(int i = 0; i < NUM_HEAPS; i++) for(int i = 0; i < NUM_HEAPS; i++)
printf("# heap %i: %p -- %p -> %p (%li of %li free)\n", i, heap_start[i], heap[i], heap_max[i], printf("# heap %i: %p -- %p -> %p (%li of %li free)\n", i, heap_start[i], heap[i], heap_max[i],
(uint32_t)heap_max[i] - (uint32_t)heap[i], (uint32_t)heap_max[i] - (uint32_t)heap_start[i]); (uint32_t)heap_max[i] - (uint32_t)heap[i], (uint32_t)heap_max[i] - (uint32_t)heap_start[i]);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -100,7 +100,7 @@ void __assert_func(const char *file, int line, const char *func, const char *fai
trace_number(TRACELOG_EV_ASSERTION, line); trace_number(TRACELOG_EV_ASSERTION, line);
syslog(SL_EMERGENCY, "assert", "%s() in %s:%u\n", func, file, line); syslog(SL_EMERGENCY, "assert", "%s() in %s:%u\n", func, file, line);
#endif #endif
printf("#! assertion %s failed\n\t%s() in %s:%u\n", failedexpr, func, file, line ); printf("#! assertion %s failed\n\t%s() in %s:%u\n", failedexpr, func, file, line);
_exit(3); _exit(3);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -111,8 +111,7 @@ void __assert(const char *file, int line, const char *failedexpr)
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
caddr_t _sbrk_r(struct _reent *r, size_t incr) caddr_t _sbrk_r(struct _reent *r, size_t incr)
{ {
if(incr < 0) if(incr < 0) {
{
puts("[syscalls] Negative Values for _sbrk_r are not supported"); puts("[syscalls] Negative Values for _sbrk_r are not supported");
r->_errno = ENOMEM; r->_errno = ENOMEM;
return NULL; return NULL;
@ -121,17 +120,18 @@ caddr_t _sbrk_r(struct _reent *r, size_t incr)
uint32_t cpsr = disableIRQ(); uint32_t cpsr = disableIRQ();
/* check all heaps for a chunk of the requested size */ /* check all heaps for a chunk of the requested size */
for (; iUsedHeap < NUM_HEAPS; iUsedHeap++ ) { for(; iUsedHeap < NUM_HEAPS; iUsedHeap++) {
caddr_t new_heap = heap[iUsedHeap] + incr; caddr_t new_heap = heap[iUsedHeap] + incr;
#ifdef MODULE_TRACELOG #ifdef MODULE_TRACELOG
trace_pointer(TRACELOG_EV_MEMORY, heap[iUsedHeap]); trace_pointer(TRACELOG_EV_MEMORY, heap[iUsedHeap]);
#endif #endif
if( new_heap <= heap_max[iUsedHeap] ) {
if(new_heap <= heap_max[iUsedHeap]) {
caddr_t prev_heap = heap[iUsedHeap]; caddr_t prev_heap = heap[iUsedHeap];
#ifdef MODULE_TRACELOG #ifdef MODULE_TRACELOG
trace_pointer(TRACELOG_EV_MEMORY, new_heap); trace_pointer(TRACELOG_EV_MEMORY, new_heap);
#endif #endif
heap[iUsedHeap] = new_heap; heap[iUsedHeap] = new_heap;
r->_errno = 0; r->_errno = 0;
@ -139,10 +139,11 @@ caddr_t _sbrk_r(struct _reent *r, size_t incr)
return prev_heap; return prev_heap;
} }
} }
restoreIRQ(cpsr); restoreIRQ(cpsr);
#ifdef MODULE_TRACELOG #ifdef MODULE_TRACELOG
trace_string(TRACELOG_EV_MEMORY, "heap!"); // heap full trace_string(TRACELOG_EV_MEMORY, "heap!"); // heap full
#endif #endif
r->_errno = ENOMEM; r->_errno = ENOMEM;
return NULL; return NULL;
@ -151,10 +152,13 @@ caddr_t _sbrk_r(struct _reent *r, size_t incr)
int _isatty_r(struct _reent *r, int fd) int _isatty_r(struct _reent *r, int fd)
{ {
r->_errno = 0; r->_errno = 0;
if( fd == STDOUT_FILENO || fd == STDERR_FILENO )
if(fd == STDOUT_FILENO || fd == STDERR_FILENO) {
return 1; return 1;
else }
else {
return 0; return 0;
}
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
_off_t _lseek_r(struct _reent *r, int fd, _off_t pos, int whence) _off_t _lseek_r(struct _reent *r, int fd, _off_t pos, int whence)
@ -178,7 +182,7 @@ int _open_r(struct _reent *r, const char *name, int mode)
r->_errno = ENODEV; // no such device r->_errno = ENODEV; // no such device
#ifdef MODULE_FAT #ifdef MODULE_FAT
ret = ff_open_r(r,name,mode); ret = ff_open_r(r, name, mode);
#endif #endif
PRINTF("open [%i] errno %i\n", ret, r->_errno); PRINTF("open [%i] errno %i\n", ret, r->_errno);
@ -191,33 +195,36 @@ int _stat_r(struct _reent *r, char *name, struct stat *st)
PRINTF("_stat_r '%s' \n", name); PRINTF("_stat_r '%s' \n", name);
r->_errno = ENODEV; // no such device r->_errno = ENODEV; // no such device
#ifdef MODULE_FAT #ifdef MODULE_FAT
ret = ff_stat_r(r,name,st); ret = ff_stat_r(r, name, st);
#endif #endif
PRINTF("_stat_r [%i] errno %i\n", ret, r->_errno); PRINTF("_stat_r [%i] errno %i\n", ret, r->_errno);
return ret; return ret;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int _fstat_r(struct _reent *r, int fd, struct stat * st) int _fstat_r(struct _reent *r, int fd, struct stat *st)
{ {
int ret = -1; int ret = -1;
r->_errno = 0; r->_errno = 0;
memset(st, 0, sizeof(*st)); memset(st, 0, sizeof(*st));
if( fd == STDOUT_FILENO || fd == STDERR_FILENO ) {
if(fd == STDOUT_FILENO || fd == STDERR_FILENO) {
st->st_mode = S_IFCHR; st->st_mode = S_IFCHR;
ret = 0; ret = 0;
} else { }
else {
#ifdef MODULE_FAT #ifdef MODULE_FAT
PRINTF("_fstat_r '%i' \n", fd); PRINTF("_fstat_r '%i' \n", fd);
ret = ff_fstat_r(r,fd,st); ret = ff_fstat_r(r, fd, st);
PRINTF("_fstat_r [%i] errno %i\n", ret, r->_errno); PRINTF("_fstat_r [%i] errno %i\n", ret, r->_errno);
#else #else
r->_errno = ENODEV; r->_errno = ENODEV;
#endif #endif
} }
return ret; return ret;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -229,20 +236,23 @@ int _write_r(struct _reent *r, int fd, const void *data, unsigned int count)
switch(fd) { switch(fd) {
case STDOUT_FILENO: case STDOUT_FILENO:
case STDERR_FILENO: case STDERR_FILENO:
#if FEUERWARE_CONF_ENABLE_HAL #if FEUERWARE_CONF_ENABLE_HAL
if( stdio != NULL ) if(stdio != NULL) {
result = chardevice_write(stdio, (char*)data, count); result = chardevice_write(stdio, (char *)data, count);
else if( hal_state == HAL_NOT_INITIALIZED ) }
result = fw_puts((char*)data, count); else if(hal_state == HAL_NOT_INITIALIZED) {
#else result = fw_puts((char *)data, count);
result = fw_puts((char*)data, count); }
#endif
#else
result = fw_puts((char *)data, count);
#endif
break; break;
default: default:
#ifdef MODULE_FAT #ifdef MODULE_FAT
result = ff_write_r(r, fd, data, count); result = ff_write_r(r, fd, data, count);
#endif #endif
PRINTF("write [%i] data @%p count %i\n", fd, data, count); PRINTF("write [%i] data @%p count %i\n", fd, data, count);
PRINTF("write [%i] returned %i errno %i\n", fd, result, r->_errno); PRINTF("write [%i] returned %i errno %i\n", fd, result, r->_errno);
@ -269,16 +279,16 @@ int _close_r(struct _reent *r, int fd)
{ {
int result = -1; int result = -1;
r->_errno = EBADF; r->_errno = EBADF;
#ifdef MODULE_FAT #ifdef MODULE_FAT
ret = ff_close_r(r, fd); ret = ff_close_r(r, fd);
#endif #endif
PRINTF("close [%i]\n", fd); PRINTF("close [%i]\n", fd);
PRINTF("close returned %i errno %i\n", result, errno); PRINTF("close returned %i errno %i\n", result, errno);
return result; return result;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int _unlink_r(struct _reent *r, char* path) int _unlink_r(struct _reent *r, char *path)
{ {
int result = -1; int result = -1;
r->_errno = ENODEV; r->_errno = ENODEV;
@ -300,6 +310,7 @@ void _exit(int n)
stdio_flush(); stdio_flush();
arm_reset(); arm_reset();
while(1); while(1);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -315,5 +326,5 @@ int _kill_r(struct _reent *r, int pid, int sig)
return -1; return -1;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void _init(void){} void _init(void) {}
void _fini(void){} void _fini(void) {}

View File

@ -5,100 +5,108 @@
#include <board.h> #include <board.h>
#include <hwtimer.h> #include <hwtimer.h>
// ************************************************************************************************* /**************************************************************************************************
// @fn Strobe * @fn Strobe
// @brief Send command to radio. * @brief Send command to radio.
// @param none * @param none
// @return none * @return none
// ************************************************************************************************* *************************************************************************************************/
uint8_t cc110x_strobe(uint8_t c) { uint8_t cc110x_strobe(uint8_t c)
uint8_t statusByte = 0; {
uint16_t int_state, gdo_state; uint8_t statusByte = 0;
uint16_t int_state, gdo_state;
// Check for valid strobe command /* Check for valid strobe command */
if((c == 0xBD) || ((c > RF_SRES) && (c < RF_SNOP))) { if((c == 0xBD) || ((c > RF_SRES) && (c < RF_SNOP))) {
int_state = disableIRQ(); int_state = disableIRQ();
// Clear the Status read flag /* Clear the Status read flag */
RF1AIFCTL1 &= ~(RFSTATIFG); RF1AIFCTL1 &= ~(RFSTATIFG);
// Wait for radio to be ready for next instruction /* Wait for radio to be ready for next instruction */
while( !(RF1AIFCTL1 & RFINSTRIFG)); while(!(RF1AIFCTL1 & RFINSTRIFG));
// Write the strobe instruction /* Write the strobe instruction */
if ((c > RF_SRES) && (c < RF_SNOP)) if((c > RF_SRES) && (c < RF_SNOP)) {
{
gdo_state = cc110x_read_reg(IOCFG2); // buffer IOCFG2 state gdo_state = cc110x_read_reg(IOCFG2); /* buffer IOCFG2 state */
cc110x_write_reg(IOCFG2, 0x29); // c-ready to GDO2 cc110x_write_reg(IOCFG2, 0x29); /* c-ready to GDO2 */
RF1AINSTRB = c; RF1AINSTRB = c;
if ((RF1AIN & 0x04) == 0x04 ) // chip at sleep mode
{ if((RF1AIN & 0x04) == 0x04) { /* chip at sleep mode */
if ((c == RF_SXOFF) || (c == RF_SPWD) || (c == RF_SWOR) ) { } if((c == RF_SXOFF) || (c == RF_SPWD) || (c == RF_SWOR)) { }
else else {
{ while((RF1AIN & 0x04) == 0x04); /* c-ready ? */
while ((RF1AIN&0x04)== 0x04); // c-ready ?
hwtimer_wait(RTIMER_TICKS(9800)); // Delay for ~810usec at 12MHz CPU clock hwtimer_wait(RTIMER_TICKS(9800)); /* Delay for ~810usec at 12MHz CPU clock */
} }
} }
cc110x_write_reg(IOCFG2, gdo_state); // restore IOCFG2 setting
} cc110x_write_reg(IOCFG2, gdo_state); /* restore IOCFG2 setting */
else // chip active mode }
{ else { /* chip active mode */
RF1AINSTRB = c; RF1AINSTRB = c;
} }
statusByte = RF1ASTATB;
while( !(RF1AIFCTL1 & RFSTATIFG) ); statusByte = RF1ASTATB;
restoreIRQ(int_state);
} while(!(RF1AIFCTL1 & RFSTATIFG));
return statusByte;
restoreIRQ(int_state);
}
return statusByte;
} }
// ************************************************************************************************* /***************************************************************************************************
// @fn cc110x_read_reg * @fn cc110x_read_reg
// @brief Read byte from register. * @brief Read byte from register.
// @param none * @param none
// @return none * @return none
// ************************************************************************************************* ***************************************************************************************************/
uint8_t cc110x_read_reg(uint8_t addr) { uint8_t cc110x_read_reg(uint8_t addr)
unsigned char x; {
uint16_t int_state; unsigned char x;
uint16_t int_state;
int_state = disableIRQ();
RF1AINSTR1B = (addr | RF_REGRD);
x = RF1ADOUT1B;
restoreIRQ(int_state);
return x;
}
// *************************************************************************************************
// @fn cc110x_write_reg
// @brief Write byte to register.
// @param none
// @return none
// *************************************************************************************************
void cc110x_write_reg(uint8_t addr, uint8_t value) {
volatile unsigned int i;
uint16_t int_state;
int_state = disableIRQ(); int_state = disableIRQ();
while (!(RF1AIFCTL1 & RFINSTRIFG)); // Wait for the Radio to be ready for the next instruction RF1AINSTR1B = (addr | RF_REGRD);
x = RF1ADOUT1B;
RF1AINSTRW = ((addr | RF_REGWR)<<8 ) + value; // Send address + Instruction restoreIRQ(int_state);
while (!(RFDINIFG & RF1AIFCTL1)); return x;
}
i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status byte
/**************************************************************************************************
* @fn cc110x_write_reg
* @brief Write byte to register.
* @param none
* @return none
**************************************************************************************************/
void cc110x_write_reg(uint8_t addr, uint8_t value)
{
volatile unsigned int i;
uint16_t int_state;
int_state = disableIRQ();
while(!(RF1AIFCTL1 & RFINSTRIFG)); /* Wait for the Radio to be ready for the next instruction */
RF1AINSTRW = ((addr | RF_REGWR) << 8) + value; /* Send address + Instruction */
while(!(RFDINIFG & RF1AIFCTL1));
i = RF1ADOUTB; /* Reset RFDOUTIFG flag which contains status byte */
restoreIRQ(int_state); restoreIRQ(int_state);
} }
uint8_t cc110x_read_status(uint8_t addr) { uint8_t cc110x_read_status(uint8_t addr)
{
unsigned char x; unsigned char x;
uint16_t int_state; uint16_t int_state;
@ -111,73 +119,82 @@ uint8_t cc110x_read_status(uint8_t addr) {
return x; return x;
} }
// ************************************************************************************************* /****************************************************************************************************
// @fn cc110x_readburst_reg * @fn cc110x_readburst_reg
// @brief Read sequence of bytes from register. * @brief Read sequence of bytes from register.
// @param none * @param none
// @return none * @return none
// ************************************************************************************************* ***************************************************************************************************/
void cc110x_readburst_reg(uint8_t addr, char *buffer, uint8_t count) { void cc110x_readburst_reg(uint8_t addr, char *buffer, uint8_t count)
unsigned int i; {
uint16_t int_state; unsigned int i;
uint16_t int_state;
int_state = disableIRQ(); int_state = disableIRQ();
while (!(RF1AIFCTL1 & RFINSTRIFG)); // Wait for the Radio to be ready for next instruction while(!(RF1AIFCTL1 & RFINSTRIFG)); /* Wait for the Radio to be ready for next instruction */
RF1AINSTR1B = (addr | RF_REGRD); // Send address + Instruction
for (i = 0; i < (count-1); i++) RF1AINSTR1B = (addr | RF_REGRD); /* Send address + Instruction */
{
while (!(RFDOUTIFG&RF1AIFCTL1)); // Wait for the Radio Core to update the RF1ADOUTB reg for(i = 0; i < (count - 1); i++) {
buffer[i] = RF1ADOUT1B; // Read DOUT from Radio Core + clears RFDOUTIFG while(!(RFDOUTIFG & RF1AIFCTL1)); /* Wait for the Radio Core to update the RF1ADOUTB reg */
// Also initiates auo-read for next DOUT byte
} buffer[i] = RF1ADOUT1B; /* Read DOUT from Radio Core + clears RFDOUTIFG */
buffer[count-1] = RF1ADOUT0B; // Store the last DOUT from Radio Core /* Also initiates auo-read for next DOUT byte */
}
buffer[count - 1] = RF1ADOUT0B; /* Store the last DOUT from Radio Core */
restoreIRQ(int_state); restoreIRQ(int_state);
} }
void cc110x_read_fifo(char *buffer, uint8_t count) { void cc110x_read_fifo(char *buffer, uint8_t count)
unsigned int i; {
uint16_t int_state; unsigned int i;
uint16_t int_state;
int_state = disableIRQ(); int_state = disableIRQ();
while (!(RF1AIFCTL1 & RFINSTRIFG)); // Wait for the Radio to be ready for next instruction while(!(RF1AIFCTL1 & RFINSTRIFG)); /* Wait for the Radio to be ready for next instruction */
RF1AINSTR1B = (RF_RXFIFORD); // Send address + Instruction
for (i = 0; i < (count-1); i++) RF1AINSTR1B = (RF_RXFIFORD); /* Send address + Instruction */
{
while (!(RFDOUTIFG&RF1AIFCTL1)); // Wait for the Radio Core to update the RF1ADOUTB reg for(i = 0; i < (count - 1); i++) {
buffer[i] = RF1ADOUT1B; // Read DOUT from Radio Core + clears RFDOUTIFG while(!(RFDOUTIFG & RF1AIFCTL1)); /* Wait for the Radio Core to update the RF1ADOUTB reg */
// Also initiates auo-read for next DOUT byte
} buffer[i] = RF1ADOUT1B; /* Read DOUT from Radio Core + clears RFDOUTIFG */
buffer[count-1] = RF1ADOUT0B; // Store the last DOUT from Radio Core /* Also initiates auo-read for next DOUT byte */
}
buffer[count - 1] = RF1ADOUT0B; /* Store the last DOUT from Radio Core */
restoreIRQ(int_state); restoreIRQ(int_state);
} }
// ************************************************************************************************* /***************************************************************************************************
// @fn cc110x_writeburst_reg * @fn cc110x_writeburst_reg
// @brief Write sequence of bytes to register. * @brief Write sequence of bytes to register.
// @param none * @param none
// @return none * @return none
// ************************************************************************************************* **************************************************************************************************/
uint8_t cc110x_writeburst_reg(uint8_t addr, char *buffer, uint8_t count) { uint8_t cc110x_writeburst_reg(uint8_t addr, char *buffer, uint8_t count)
// Write Burst works wordwise not bytewise - bug known already {
unsigned char i; /* Write Burst works wordwise not bytewise - bug known already */
uint16_t int_state; unsigned char i;
uint16_t int_state;
int_state = disableIRQ(); int_state = disableIRQ();
while (!(RF1AIFCTL1 & RFINSTRIFG)); // Wait for the Radio to be ready for next instruction while(!(RF1AIFCTL1 & RFINSTRIFG)); /* Wait for the Radio to be ready for next instruction */
RF1AINSTRW = ((addr | RF_REGWR)<<8 ) + buffer[0]; // Send address + Instruction
for (i = 1; i < count; i++) RF1AINSTRW = ((addr | RF_REGWR) << 8) + buffer[0]; /* Send address + Instruction */
{
RF1ADINB = buffer[i]; // Send data for(i = 1; i < count; i++) {
while (!(RFDINIFG & RF1AIFCTL1)); // Wait for TX to finish RF1ADINB = buffer[i]; /* Send data */
}
i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status byte while(!(RFDINIFG & RF1AIFCTL1)); /* Wait for TX to finish */
}
i = RF1ADOUTB; /* Reset RFDOUTIFG flag which contains status byte */
restoreIRQ(int_state); restoreIRQ(int_state);
return count; return count;

View File

@ -44,60 +44,64 @@
uint16_t adc12_result; uint16_t adc12_result;
uint8_t adc12_data_ready; uint8_t adc12_data_ready;
/* ************************************************************************************************* /************************************************************************************************
* @fn adc12_single_conversion * @fn adc12_single_conversion
* @brief Init ADC12. Do single conversion. Turn off ADC12. * @brief Init ADC12. Do single conversion. Turn off ADC12.
* @param none * @param none
* @return none * @return none
* ************************************************************************************************/ ************************************************************************************************/
uint16_t adc12_single_conversion(uint16_t ref, uint16_t sht, uint16_t channel) { uint16_t adc12_single_conversion(uint16_t ref, uint16_t sht, uint16_t channel)
/* Initialize the shared reference module */ {
REFCTL0 |= REFMSTR + ref + REFON; /* Enable internal reference (1.5V or 2.5V) */ /* Initialize the shared reference module */
REFCTL0 |= REFMSTR + ref + REFON; /* Enable internal reference (1.5V or 2.5V) */
/* Initialize ADC12_A */ /* Initialize ADC12_A */
ADC12CTL0 = sht + ADC12ON; /* Set sample time */ ADC12CTL0 = sht + ADC12ON; /* Set sample time */
ADC12CTL1 = ADC12SHP; /* Enable sample timer */ ADC12CTL1 = ADC12SHP; /* Enable sample timer */
ADC12MCTL0 = ADC12SREF_1 + channel; /* ADC input channel */ ADC12MCTL0 = ADC12SREF_1 + channel; /* ADC input channel */
ADC12IE = 0x001; /* ADC_IFG upon conv result-ADCMEMO */ ADC12IE = 0x001; /* ADC_IFG upon conv result-ADCMEMO */
eINT(); eINT();
/* Wait 2 ticks (66us) to allow internal reference to settle */ /* Wait 2 ticks (66us) to allow internal reference to settle */
hwtimer_wait(2); hwtimer_wait(2);
/* Start ADC12 */ /* Start ADC12 */
ADC12CTL0 |= ADC12ENC; ADC12CTL0 |= ADC12ENC;
/* Clear data ready flag */ /* Clear data ready flag */
adc12_data_ready = 0; adc12_data_ready = 0;
/* Sampling and conversion start */ /* Sampling and conversion start */
ADC12CTL0 |= ADC12SC; ADC12CTL0 |= ADC12SC;
/* Wait until ADC12 has finished */ /* Wait until ADC12 has finished */
hwtimer_wait(5); hwtimer_wait(5);
while (!adc12_data_ready);
/* Shut down ADC12 */ while(!adc12_data_ready);
ADC12CTL0 &= ~(ADC12ENC | ADC12SC | sht);
ADC12CTL0 &= ~ADC12ON;
/* Shut down reference voltage */ /* Shut down ADC12 */
REFCTL0 &= ~(REFMSTR + ref + REFON); ADC12CTL0 &= ~(ADC12ENC | ADC12SC | sht);
ADC12CTL0 &= ~ADC12ON;
ADC12IE = 0; /* Shut down reference voltage */
REFCTL0 &= ~(REFMSTR + ref + REFON);
/* Return ADC result */ ADC12IE = 0;
return adc12_result;
/* Return ADC result */
return adc12_result;
} }
/* ************************************************************************************************* /*************************************************************************************************
* @fn ADC12ISR * @fn ADC12ISR
* @brief Store ADC12 conversion result. Set flag to indicate data ready. * @brief Store ADC12 conversion result. Set flag to indicate data ready.
* @param none * @param none
* @return none * @return none
* ************************************************************************************************/ *************************************************************************************************/
interrupt (ADC12_VECTOR) __attribute__ ((naked)) adc_isr (void) { interrupt(ADC12_VECTOR) __attribute__((naked)) adc_isr(void)
{
__enter_isr(); __enter_isr();
switch(ADC12IV) { switch(ADC12IV) {
case 0: case 0:
break; /* Vector 0: No interrupt */ break; /* Vector 0: No interrupt */
@ -108,7 +112,7 @@ interrupt (ADC12_VECTOR) __attribute__ ((naked)) adc_isr (void) {
case 6: case 6:
/* Vector 6: ADC12IFG0 */ /* Vector 6: ADC12IFG0 */
adc12_result = ADC12MEM0; /* Move results, IFG is cleared */ adc12_result = ADC12MEM0; /* Move results, IFG is cleared */
adc12_data_ready = 1; adc12_data_ready = 1;
break; break;
case 8: case 8:
break; /* Vector 8: ADC12IFG1 */ break; /* Vector 8: ADC12IFG1 */
@ -141,6 +145,7 @@ interrupt (ADC12_VECTOR) __attribute__ ((naked)) adc_isr (void) {
default: default:
break; break;
} }
__exit_isr(); __exit_isr();
} }

View File

@ -51,37 +51,42 @@ uint16_t debounce_time[INT_PORTS][BITMASK_SIZE];
uint16_t c1 = 0, c2 = 0; uint16_t c1 = 0, c2 = 0;
void gpioint_init(void) { void gpioint_init(void)
{
uint8_t i, j; uint8_t i, j;
for (i = 0; i < INT_PORTS; i++) {
for (j = 0; j < BITMASK_SIZE; j++) { for(i = 0; i < INT_PORTS; i++) {
for(j = 0; j < BITMASK_SIZE; j++) {
cb[i][j] = NULL; cb[i][j] = NULL;
debounce_time[i][j] = 0; debounce_time[i][j] = 0;
} }
} }
} }
bool gpioint_set(int port, uint32_t bitmask, int flags, fp_irqcb callback) { bool gpioint_set(int port, uint32_t bitmask, int flags, fp_irqcb callback)
{
int8_t base; int8_t base;
if ((port >= PORTINT_MIN) && (port <= PORTINT_MAX)) { if((port >= PORTINT_MIN) && (port <= PORTINT_MAX)) {
/* set the callback function */ /* set the callback function */
base = number_of_highest_bit(bitmask); base = number_of_highest_bit(bitmask);
if (base >= 0) {
if(base >= 0) {
cb[port - PORTINT_MIN][base] = callback; cb[port - PORTINT_MIN][base] = callback;
} }
else { else {
return false; return false;
} }
if (flags & GPIOINT_DEBOUNCE) {
if(flags & GPIOINT_DEBOUNCE) {
debounce_flags[port - PORTINT_MIN] |= bitmask; debounce_flags[port - PORTINT_MIN] |= bitmask;
} }
else { else {
debounce_flags[port - PORTINT_MIN] &= ~bitmask; debounce_flags[port - PORTINT_MIN] &= ~bitmask;
} }
} }
switch (port) { switch(port) {
case 1: case 1:
/* set port to input */ /* set port to input */
P1DIR &= ~bitmask; P1DIR &= ~bitmask;
@ -93,21 +98,24 @@ bool gpioint_set(int port, uint32_t bitmask, int flags, fp_irqcb callback) {
P1IFG &= ~bitmask; P1IFG &= ~bitmask;
/* trigger on rising... */ /* trigger on rising... */
if (flags & GPIOINT_RISING_EDGE) { if(flags & GPIOINT_RISING_EDGE) {
P1IES &= bitmask; P1IES &= bitmask;
} }
/* ...or falling edge */ /* ...or falling edge */
if (flags & GPIOINT_FALLING_EDGE) { if(flags & GPIOINT_FALLING_EDGE) {
P1IES |= bitmask; P1IES |= bitmask;
} }
/* disable interrupt */ /* disable interrupt */
if (flags == GPIOINT_DISABLE) { if(flags == GPIOINT_DISABLE) {
P1IE &= ~bitmask; P1IE &= ~bitmask;
} }
/* enable interrupt */ /* enable interrupt */
P1IE |= bitmask; P1IE |= bitmask;
break; break;
case 2: case 2:
/* set port to input */ /* set port to input */
P2DIR &= ~bitmask; P2DIR &= ~bitmask;
@ -119,27 +127,31 @@ bool gpioint_set(int port, uint32_t bitmask, int flags, fp_irqcb callback) {
P2IFG &= ~bitmask; P2IFG &= ~bitmask;
/* trigger on rising... */ /* trigger on rising... */
if (flags == GPIOINT_RISING_EDGE) { if(flags == GPIOINT_RISING_EDGE) {
P2IES &= bitmask; P2IES &= bitmask;
} }
/* ...or falling edge */ /* ...or falling edge */
else if (flags == GPIOINT_FALLING_EDGE) { else if(flags == GPIOINT_FALLING_EDGE) {
P2IES |= bitmask; P2IES |= bitmask;
} }
/* or disable interrupt */ /* or disable interrupt */
else { else {
P2IE &= ~bitmask; P2IE &= ~bitmask;
} }
/* enable interrupt */ /* enable interrupt */
P2IE |= bitmask; P2IE |= bitmask;
break; break;
default:
default:
return false; return false;
} }
return 1; return 1;
} }
interrupt (PORT1_VECTOR) __attribute__ ((naked)) port1_isr(void) { interrupt(PORT1_VECTOR) __attribute__((naked)) port1_isr(void)
{
uint8_t int_enable, ifg_num, p1ifg; uint8_t int_enable, ifg_num, p1ifg;
uint16_t p1iv; uint16_t p1iv;
uint16_t diff; uint16_t diff;
@ -154,32 +166,37 @@ interrupt (PORT1_VECTOR) __attribute__ ((naked)) port1_isr(void) {
P1IE = 0x00; P1IE = 0x00;
ifg_num = (p1iv >> 1) - 1; ifg_num = (p1iv >> 1) - 1;
/* check interrupt source */ /* check interrupt source */
if (debounce_flags[0] & p1ifg) { if(debounce_flags[0] & p1ifg) {
/* check if bouncing */ /* check if bouncing */
diff = hwtimer_now() - debounce_time[0][ifg_num]; diff = hwtimer_now() - debounce_time[0][ifg_num];
if (diff > DEBOUNCE_TIMEOUT) {
if(diff > DEBOUNCE_TIMEOUT) {
debounce_time[0][ifg_num] = hwtimer_now(); debounce_time[0][ifg_num] = hwtimer_now();
if (cb[0][ifg_num] != NULL) {
if(cb[0][ifg_num] != NULL) {
cb[0][ifg_num](); cb[0][ifg_num]();
} }
} }
else { else {
/* TODO: check for long duration irq */ /* TODO: check for long duration irq */
asm volatile (" nop "); asm volatile(" nop ");
} }
} }
else { else {
if (cb[0][ifg_num] != NULL) { if(cb[0][ifg_num] != NULL) {
cb[0][ifg_num](); cb[0][ifg_num]();
} }
} }
P1IFG = 0x00;
P1IFG = 0x00;
P1IE = int_enable; P1IE = int_enable;
__exit_isr(); __exit_isr();
} }
interrupt (PORT2_VECTOR) __attribute__ ((naked)) port2_isr(void) { interrupt(PORT2_VECTOR) __attribute__((naked)) port2_isr(void)
{
uint8_t int_enable, ifg_num, p2ifg; uint8_t int_enable, ifg_num, p2ifg;
uint16_t p2iv; uint16_t p2iv;
uint16_t diff; uint16_t diff;
@ -194,34 +211,34 @@ interrupt (PORT2_VECTOR) __attribute__ ((naked)) port2_isr(void) {
P2IE = 0x00; P2IE = 0x00;
ifg_num = (p2iv >> 1) - 1; ifg_num = (p2iv >> 1) - 1;
/* check interrupt source */ /* check interrupt source */
if (debounce_flags[1] & p2ifg) { if(debounce_flags[1] & p2ifg) {
/* check if bouncing */ /* check if bouncing */
diff = hwtimer_now() - debounce_time[1][ifg_num]; diff = hwtimer_now() - debounce_time[1][ifg_num];
if (diff > DEBOUNCE_TIMEOUT) {
if(diff > DEBOUNCE_TIMEOUT) {
debounce_time[1][ifg_num] = hwtimer_now(); debounce_time[1][ifg_num] = hwtimer_now();
c1++; c1++;
if (cb[1][ifg_num] != NULL) {
if(cb[1][ifg_num] != NULL) {
cb[1][ifg_num](); cb[1][ifg_num]();
} }
} }
else { else {
c2++; c2++;
/* TODO: check for long duration irq */ /* TODO: check for long duration irq */
asm volatile (" nop "); asm volatile(" nop ");
} }
} }
else { else {
if (cb[1][ifg_num] != NULL) { if(cb[1][ifg_num] != NULL) {
cb[1][ifg_num](); cb[1][ifg_num]();
} }
} }
//else {
// cb[1][ifg_num]();
//}
P2IFG = 0x00; P2IFG = 0x00;
P2IE = int_enable; P2IE = int_enable;
__exit_isr(); __exit_isr();
} }

View File

@ -31,7 +31,8 @@ static int set_time = 0;
int rtc_second_pid = 0; int rtc_second_pid = 0;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void rtc_init(void) { void rtc_init(void)
{
/* Set to calendar mode */ /* Set to calendar mode */
RTCCTL1 |= RTCMODE_H; RTCCTL1 |= RTCMODE_H;
@ -42,25 +43,26 @@ void rtc_init(void) {
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void rtc_enable(void) { void rtc_enable(void)
{
/* Set RTC operational */ /* Set RTC operational */
RTCCTL1 &= ~RTCHOLD_H; RTCCTL1 &= ~RTCHOLD_H;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void rtc_disable(void) { void rtc_disable(void)
{
/* Stop RTC */ /* Stop RTC */
RTCCTL1 |= RTCHOLD_H; RTCCTL1 |= RTCHOLD_H;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void rtc_set_localtime(struct tm* localt) { void rtc_set_localtime(struct tm *localt)
if(localt == NULL) { {
return; if(localt == NULL) {
return;
} }
/* copy time to be set */ /* copy time to be set */
memcpy(&time_to_set, localt, sizeof(struct tm)); memcpy(&time_to_set, localt, sizeof(struct tm));
/* set interrupt to set this time after the next transition */
// RTCCTL0 |= RTCRDYIE;
set_time = 1; set_time = 1;
} }
@ -83,45 +85,54 @@ time_t rtc_time(void) {
} }
*/ */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void rtc_get_localtime(struct tm* localt) { void rtc_get_localtime(struct tm *localt)
{
uint8_t success = 0; uint8_t success = 0;
uint8_t i; uint8_t i;
uint16_t tmpyear; uint16_t tmpyear;
if( localt == NULL ) { if(localt == NULL) {
return; return;
} }
while (!success) { while(!success) {
for (i = 0; i < 8; i++) { for(i = 0; i < 8; i++) {
/* try again when RTC is in transition */ /* try again when RTC is in transition */
if (!(RTCCTL1 & RTCRDY_H)) { if(!(RTCCTL1 & RTCRDY_H)) {
break; break;
} }
switch (i) {
switch(i) {
case 0: case 0:
localt->tm_sec = RTCSEC; localt->tm_sec = RTCSEC;
break; break;
case 1: case 1:
localt->tm_min = RTCMIN; localt->tm_min = RTCMIN;
break; break;
case 2: case 2:
localt->tm_hour = RTCHOUR; localt->tm_hour = RTCHOUR;
break; break;
case 3: case 3:
localt->tm_mday = RTCDAY; localt->tm_mday = RTCDAY;
break; break;
case 4: case 4:
localt->tm_wday = RTCDOW; localt->tm_wday = RTCDOW;
break; break;
case 5: case 5:
localt->tm_mon = RTCMON - 1; localt->tm_mon = RTCMON - 1;
break; break;
case 6: case 6:
tmpyear = RTCYEARL; tmpyear = RTCYEARL;
tmpyear |= (RTCYEARH << 0x08); tmpyear |= (RTCYEARH << 0x08);
localt->tm_year = tmpyear - 1900; localt->tm_year = tmpyear - 1900;
break; break;
default: default:
success = 1; success = 1;
break; break;
@ -131,28 +142,34 @@ void rtc_get_localtime(struct tm* localt) {
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void rtc_set_alarm(struct tm* localt, rtc_alarm_mask_t mask) { void rtc_set_alarm(struct tm *localt, rtc_alarm_mask_t mask)
if (mask & RTC_ALARM_MIN) { {
if(mask & RTC_ALARM_MIN) {
RTCAMIN = localt->tm_min; RTCAMIN = localt->tm_min;
RTCAMIN |= BIT7; RTCAMIN |= BIT7;
} }
if (mask & RTC_ALARM_HOUR) {
if(mask & RTC_ALARM_HOUR) {
RTCAHOUR = localt->tm_hour; RTCAHOUR = localt->tm_hour;
RTCAHOUR |= BIT7; RTCAHOUR |= BIT7;
} }
if (mask & RTC_ALARM_DOW) {
if(mask & RTC_ALARM_DOW) {
RTCADOW = localt->tm_wday; RTCADOW = localt->tm_wday;
RTCADOW |= BIT7; RTCADOW |= BIT7;
} }
if (mask & RTC_ALARM_DOM) {
if(mask & RTC_ALARM_DOM) {
RTCADAY = localt->tm_mday; RTCADAY = localt->tm_mday;
RTCADAY |= BIT7; RTCADAY |= BIT7;
} }
RTCCTL0 |= RTCAIE; RTCCTL0 |= RTCAIE;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void rtc_remove_alarm(void) { void rtc_remove_alarm(void)
{
/* reset all AE bits */ /* reset all AE bits */
RTCAHOUR &= ~BIT7; RTCAHOUR &= ~BIT7;
RTCAMIN &= ~BIT7; RTCAMIN &= ~BIT7;
@ -163,16 +180,18 @@ void rtc_remove_alarm(void) {
RTCCTL0 &= ~RTCAIE; RTCCTL0 &= ~RTCAIE;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
interrupt(RTC_VECTOR) __attribute__ ((naked)) rtc_isr(void) { interrupt(RTC_VECTOR) __attribute__((naked)) rtc_isr(void)
{
__enter_isr(); __enter_isr();
/* RTC is save to write for up to one second now */ /* RTC is save to write for up to one second now */
if (RTCIV == RTC_RTCRDYIFG) { if(RTCIV == RTC_RTCRDYIFG) {
/* disable interrupt */ /* disable interrupt */
//RTCCTL0 &= ~RTCRDYIE; //RTCCTL0 &= ~RTCRDYIE;
if (set_time) { if(set_time) {
set_time = 0; set_time = 0;
/* set previous set time and reset it */ /* set previous set time and reset it */
RTCSEC = time_to_set.tm_sec; RTCSEC = time_to_set.tm_sec;
RTCMIN = time_to_set.tm_min; RTCMIN = time_to_set.tm_min;
RTCHOUR = time_to_set.tm_hour; RTCHOUR = time_to_set.tm_hour;
@ -182,14 +201,16 @@ interrupt(RTC_VECTOR) __attribute__ ((naked)) rtc_isr(void) {
RTCYEARL = (time_to_set.tm_year + 1900) & 0xFF; RTCYEARL = (time_to_set.tm_year + 1900) & 0xFF;
RTCYEARH = (time_to_set.tm_year + 1900) >> 0x08; RTCYEARH = (time_to_set.tm_year + 1900) >> 0x08;
} }
if (rtc_second_pid) {
if(rtc_second_pid) {
msg_t m; msg_t m;
m.type = RTC_SECOND; m.type = RTC_SECOND;
msg_send_int(&m, rtc_second_pid); msg_send_int(&m, rtc_second_pid);
} }
} }
/* RTC alarm */ /* RTC alarm */
else if (RTCIV == RTC_RTCAIFG) { else if(RTCIV == RTC_RTCAIFG) {
} }
__exit_isr(); __exit_isr();
} }

View File

@ -14,23 +14,24 @@ extern void TA0_unset(short timer);
void timerA_init(void) void timerA_init(void)
{ {
ticks = 0; // Set tick counter value to 0 ticks = 0; // Set tick counter value to 0
TA0CTL = TASSEL_1 + TACLR; // Clear the timer counter, set ACLK TA0CTL = TASSEL_1 + TACLR; // Clear the timer counter, set ACLK
TA0CTL &= ~TAIE; // Clear the IFG TA0CTL &= ~TAIE; // Clear the IFG
volatile unsigned int *ccr = &TA0CCR0; volatile unsigned int *ccr = &TA0CCR0;
volatile unsigned int *ctl = &TA0CCTL0; volatile unsigned int *ctl = &TA0CCTL0;
for (int i = 0; i < ARCH_MAXTIMERS; i++) { for(int i = 0; i < ARCH_MAXTIMERS; i++) {
*(ccr+i) = 0; *(ccr + i) = 0;
*(ctl+i) &= ~(CCIFG); *(ctl + i) &= ~(CCIFG);
*(ctl+i) &= ~(CCIE); *(ctl + i) &= ~(CCIE);
} }
TA0CTL |= MC_2; TA0CTL |= MC_2;
} }
interrupt(TIMER0_A0_VECTOR) __attribute__ ((naked)) timer0_a0_isr(void) { interrupt(TIMER0_A0_VECTOR) __attribute__((naked)) timer0_a0_isr(void)
{
__enter_isr(); __enter_isr();
TA0_unset(0); TA0_unset(0);
@ -38,20 +39,21 @@ interrupt(TIMER0_A0_VECTOR) __attribute__ ((naked)) timer0_a0_isr(void) {
__exit_isr(); __exit_isr();
} }
interrupt(TIMER0_A1_VECTOR) __attribute__ ((naked)) timer0_a1_5_isr(void) { interrupt(TIMER0_A1_VECTOR) __attribute__((naked)) timer0_a1_5_isr(void)
{
__enter_isr(); __enter_isr();
short taiv = TA0IV; short taiv = TA0IV;
short timer; short timer;
if (taiv & TAIFG) { if(taiv & TAIFG) {
DEBUG("Overflow\n"); DEBUG("Overflow\n");
} }
else { else {
timer = (taiv/2); timer = (taiv / 2);
TA0_unset(timer); TA0_unset(timer);
int_handler(timer); int_handler(timer);
} }
__exit_isr(); __exit_isr();
} }

View File

@ -33,10 +33,10 @@ License. See the file LICENSE in the top level directory for more details.
* @see ::rtc_set_alarm * @see ::rtc_set_alarm
*/ */
typedef enum { typedef enum {
RTC_ALARM_DISABLED = 0x00, ///< Alarm disables RTC_ALARM_DISABLED = 0x00, ///< Alarm disables
RTC_ALARM_MIN = 0x01, ///< Alarm mask for Minutes RTC_ALARM_MIN = 0x01, ///< Alarm mask for Minutes
RTC_ALARM_HOUR = 0x02, ///< Alarm mask for Hours RTC_ALARM_HOUR = 0x02, ///< Alarm mask for Hours
RTC_ALARM_DOW = 0x04, ///< Alarm mask for Day of Week RTC_ALARM_DOW = 0x04, ///< Alarm mask for Day of Week
RTC_ALARM_DOM = 0x08 ///< Alarm mask for Day of Month RTC_ALARM_DOM = 0x08 ///< Alarm mask for Day of Month
} rtc_alarm_mask_t; } rtc_alarm_mask_t;
@ -50,7 +50,7 @@ typedef enum {
* *
* @see ::rtc_alarm_mask * @see ::rtc_alarm_mask
*/ */
void rtc_set_alarm(struct tm* localti, rtc_alarm_mask_t mask); void rtc_set_alarm(struct tm *localti, rtc_alarm_mask_t mask);
/** /**
* @brief Resets any set alarm * @brief Resets any set alarm

View File

@ -2,7 +2,8 @@
#include "bits.h" #include "bits.h"
#include "VIC.h" #include "VIC.h"
void cpu_clock_scale(uint32_t source, uint32_t target, uint32_t* prescale) { void cpu_clock_scale(uint32_t source, uint32_t target, uint32_t *prescale)
{
*prescale = source / PCLK_DIV / target; *prescale = source / PCLK_DIV / target;
} }
@ -17,25 +18,24 @@ void cpu_clock_scale(uint32_t source, uint32_t target, uint32_t* prescale) {
******************************************************************************/ ******************************************************************************/
#define VIC_BASE_ADDR 0xFFFFF000 #define VIC_BASE_ADDR 0xFFFFF000
bool cpu_install_irq( int IntNumber, void *HandlerAddr, int Priority ) bool cpu_install_irq(int IntNumber, void *HandlerAddr, int Priority)
{ {
int *vect_addr; int *vect_addr;
int *vect_cntl; int *vect_cntl;
VICIntEnClear = 1 << IntNumber; /* Disable Interrupt */ VICIntEnClear = 1 << IntNumber; /* Disable Interrupt */
if ( IntNumber >= VIC_SIZE )
{
return ( false );
}
else
{
/* find first un-assigned VIC address for the handler */
vect_addr = (int *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + Priority*4);
vect_cntl = (int *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + Priority*4);
*vect_addr = (int)HandlerAddr; /* set interrupt vector */ if(IntNumber >= VIC_SIZE) {
*vect_cntl = IntNumber + BIT5; return (false);
VICIntEnable = 1 << IntNumber; /* Enable Interrupt */ }
return( true ); else {
/* find first un-assigned VIC address for the handler */
vect_addr = (int *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + Priority * 4);
vect_cntl = (int *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + Priority * 4);
*vect_addr = (int)HandlerAddr; /* set interrupt vector */
*vect_cntl = IntNumber + BIT5;
VICIntEnable = 1 << IntNumber; /* Enable Interrupt */
return(true);
} }
} }

View File

@ -19,38 +19,44 @@ License. See the file LICENSE in the top level directory for more details.
#include <stdint.h> #include <stdint.h>
#include "VIC.h" #include "VIC.h"
void lpc2387_pclk_scale(uint32_t source, uint32_t target, uint32_t* pclksel, uint32_t* prescale) void lpc2387_pclk_scale(uint32_t source, uint32_t target, uint32_t *pclksel, uint32_t *prescale)
{ {
uint32_t pclkdiv; uint32_t pclkdiv;
*prescale = source / target; *prescale = source / target;
if( (*prescale % 16) == 0 ) { if((*prescale % 16) == 0) {
*pclksel = 3; *pclksel = 3;
pclkdiv = 8; pclkdiv = 8;
} else if( (*prescale % 8) == 0 ) { }
*pclksel = 0; else if((*prescale % 8) == 0) {
pclkdiv = 4; *pclksel = 0;
} else if( (*prescale % 4) == 0 ) { pclkdiv = 4;
*pclksel = 2; }
pclkdiv = 2; else if((*prescale % 4) == 0) {
} else { *pclksel = 2;
*pclksel = 1; pclkdiv = 2;
pclkdiv = 1; }
} else {
*prescale /= pclkdiv; *pclksel = 1;
pclkdiv = 1;
}
if( *prescale % 2 ) *prescale /= pclkdiv;
(*prescale)++;
if(*prescale % 2) {
(*prescale)++;
}
} }
void cpu_clock_scale(uint32_t source, uint32_t target, uint32_t* prescale) { void cpu_clock_scale(uint32_t source, uint32_t target, uint32_t *prescale)
{
uint32_t pclksel; uint32_t pclksel;
lpc2387_pclk_scale(source, target, &pclksel, prescale); lpc2387_pclk_scale(source, target, &pclksel, prescale);
PCLKSEL0 = (PCLKSEL0 & ~(BIT2|BIT3)) | (pclksel << 2); // timer 0 PCLKSEL0 = (PCLKSEL0 & ~(BIT2 | BIT3)) | (pclksel << 2); // timer 0
PCLKSEL0 = (PCLKSEL0 & ~(BIT4|BIT5)) | (pclksel << 4); // timer 1 PCLKSEL0 = (PCLKSEL0 & ~(BIT4 | BIT5)) | (pclksel << 4); // timer 1
PCLKSEL1 = (PCLKSEL1 & ~(BIT12|BIT13)) | (pclksel << 12); // timer 2 PCLKSEL1 = (PCLKSEL1 & ~(BIT12 | BIT13)) | (pclksel << 12); // timer 2
} }
/****************************************************************************** /******************************************************************************
@ -64,25 +70,24 @@ void cpu_clock_scale(uint32_t source, uint32_t target, uint32_t* prescale) {
******************************************************************************/ ******************************************************************************/
#define VIC_BASE_ADDR 0xFFFFF000 #define VIC_BASE_ADDR 0xFFFFF000
bool install_irq( int IntNumber, void *HandlerAddr, int Priority ) bool install_irq(int IntNumber, void *HandlerAddr, int Priority)
{ {
int *vect_addr; int *vect_addr;
int *vect_cntl; int *vect_cntl;
VICIntEnClr = 1 << IntNumber; /* Disable Interrupt */ VICIntEnClr = 1 << IntNumber; /* Disable Interrupt */
if ( IntNumber >= VIC_SIZE )
{ if(IntNumber >= VIC_SIZE) {
return ( false ); return (false);
} }
else else {
{ /* find first un-assigned VIC address for the handler */
/* find first un-assigned VIC address for the handler */ vect_addr = (int *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + IntNumber * 4);
vect_addr = (int *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + IntNumber*4); vect_cntl = (int *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + IntNumber * 4);
vect_cntl = (int *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + IntNumber*4); *vect_addr = (int)HandlerAddr; /* set interrupt vector */
*vect_addr = (int)HandlerAddr; /* set interrupt vector */ *vect_cntl = Priority;
*vect_cntl = Priority; VICIntEnable = 1 << IntNumber; /* Enable Interrupt */
VICIntEnable = 1 << IntNumber; /* Enable Interrupt */ return(true);
return( true );
} }
} }

View File

@ -35,95 +35,101 @@ License. See the file LICENSE in the top level directory for more details.
#include <irq.h> #include <irq.h>
struct irq_callback_t { struct irq_callback_t {
fp_irqcb callback; fp_irqcb callback;
}; };
static struct irq_callback_t gpioint0[32]; static struct irq_callback_t gpioint0[32];
static struct irq_callback_t gpioint2[32]; static struct irq_callback_t gpioint2[32];
void gpioint_init(void) { void gpioint_init(void)
{
extern void GPIO_IRQHandler(void); extern void GPIO_IRQHandler(void);
/* GPIO Init */ /* GPIO Init */
INTWAKE |= GPIO0WAKE | GPIO2WAKE; // allow GPIO to wake up from power down INTWAKE |= GPIO0WAKE | GPIO2WAKE; /* allow GPIO to wake up from power down */
install_irq(GPIO_INT, &GPIO_IRQHandler, IRQP_GPIO); // install irq handler install_irq(GPIO_INT, &GPIO_IRQHandler, IRQP_GPIO); /* install irq handler */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
bool bool
gpioint_set(int port, uint32_t bitmask, int flags, fp_irqcb callback) gpioint_set(int port, uint32_t bitmask, int flags, fp_irqcb callback)
{ {
struct irq_callback_t* cbdata; struct irq_callback_t *cbdata;
unsigned long bit; unsigned long bit;
volatile unsigned long* en_f; volatile unsigned long *en_f;
volatile unsigned long* en_r; volatile unsigned long *en_r;
volatile unsigned long* en_clr; volatile unsigned long *en_clr;
/* lookup registers */ /* lookup registers */
bit = number_of_highest_bit(bitmask); // get irq mapping table index bit = number_of_highest_bit(bitmask); /* get irq mapping table index */
switch( port ) { switch(port) {
case 0: // PORT0 case 0: /* PORT0 */
cbdata = gpioint0; cbdata = gpioint0;
en_f = &IO0_INT_EN_F; en_f = &IO0_INT_EN_F;
en_r = &IO0_INT_EN_R; en_r = &IO0_INT_EN_R;
en_clr = &IO0_INT_CLR; en_clr = &IO0_INT_CLR;
break; break;
case 2: // PORT2 case 2: /* PORT2 */
cbdata = gpioint2; cbdata = gpioint2;
en_f = &IO2_INT_EN_F; en_f = &IO2_INT_EN_F;
en_r = &IO2_INT_EN_R; en_r = &IO2_INT_EN_R;
en_clr = &IO2_INT_CLR; en_clr = &IO2_INT_CLR;
break; break;
default: // unsupported default: /* unsupported */
return false; // fail return false; /* fail */
} }
/* reconfigure irq */ /* reconfigure irq */
unsigned long cpsr = disableIRQ(); unsigned long cpsr = disableIRQ();
*en_clr |= bitmask; // clear interrupt *en_clr |= bitmask; /* clear interrupt */
if( (flags & GPIOINT_FALLING_EDGE) != 0 ) { if((flags & GPIOINT_FALLING_EDGE) != 0) {
*en_f |= bitmask; // enable falling edge *en_f |= bitmask; /* enable falling edge */
} else { }
*en_f &= ~bitmask; // disable falling edge else {
} *en_f &= ~bitmask; /* disable falling edge */
}
if( (flags & GPIOINT_RISING_EDGE) != 0 ) { if((flags & GPIOINT_RISING_EDGE) != 0) {
*en_r |= bitmask; // enable rising edge *en_r |= bitmask; /* enable rising edge */
} else { }
*en_r &= ~bitmask; // disable rising edge else {
} *en_r &= ~bitmask; /* disable rising edge */
}
if( ((flags & (GPIOINT_FALLING_EDGE | GPIOINT_RISING_EDGE)) != 0) ) { if(((flags & (GPIOINT_FALLING_EDGE | GPIOINT_RISING_EDGE)) != 0)) {
cbdata[bit].callback = callback; cbdata[bit].callback = callback;
} else { }
cbdata[bit].callback = NULL; // remove from interrupt mapping table else {
} cbdata[bit].callback = NULL; /* remove from interrupt mapping table */
restoreIRQ(cpsr); }
return true; // success restoreIRQ(cpsr);
return true; /* success */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void __attribute__ ((__no_instrument_function__)) test_irq(int port, unsigned long f_mask, unsigned long r_mask, struct irq_callback_t* pcb) static void __attribute__((__no_instrument_function__)) test_irq(int port, unsigned long f_mask, unsigned long r_mask, struct irq_callback_t *pcb)
{ {
/* Test each bit of rising and falling masks, if set trigger interrupt /* Test each bit of rising and falling masks, if set trigger interrupt
* on corresponding device */ * on corresponding device */
do { do {
if( (pcb->callback != NULL) ) { if((pcb->callback != NULL)) {
if ((r_mask & 1) | (f_mask & 1)) { if((r_mask & 1) | (f_mask & 1)) {
pcb->callback(); // pass to handler pcb->callback(); /* pass to handler */
} }
} }
f_mask >>= 1UL; f_mask >>= 1UL;
r_mask >>= 1UL; r_mask >>= 1UL;
pcb++; pcb++;
} while( (f_mask != 0) || (r_mask != 0) ); }
while((f_mask != 0) || (r_mask != 0));
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void GPIO_IRQHandler(void) __attribute__((interrupt("IRQ"))); void GPIO_IRQHandler(void) __attribute__((interrupt("IRQ")));
@ -134,27 +140,29 @@ void GPIO_IRQHandler(void) __attribute__((interrupt("IRQ")));
* Invoked whenever an activated gpio interrupt is triggered by a rising * Invoked whenever an activated gpio interrupt is triggered by a rising
* or falling edge. * or falling edge.
*/ */
void __attribute__ ((__no_instrument_function__)) GPIO_IRQHandler(void) { void __attribute__((__no_instrument_function__)) GPIO_IRQHandler(void)
if( IO_INT_STAT & BIT0 ) { // interrupt(s) on PORT0 pending {
unsigned long int_stat_f = IO0_INT_STAT_F; // save content if(IO_INT_STAT & BIT0) { /* interrupt(s) on PORT0 pending */
unsigned long int_stat_r = IO0_INT_STAT_R; // save content unsigned long int_stat_f = IO0_INT_STAT_F; /* save content */
unsigned long int_stat_r = IO0_INT_STAT_R; /* save content */
IO0_INT_CLR = int_stat_f; // clear flags of fallen pins IO0_INT_CLR = int_stat_f; /* clear flags of fallen pins */
IO0_INT_CLR = int_stat_r; // clear flags of risen pins IO0_INT_CLR = int_stat_r; /* clear flags of risen pins */
test_irq(0, int_stat_f, int_stat_r, gpioint0); test_irq(0, int_stat_f, int_stat_r, gpioint0);
} }
if( IO_INT_STAT & BIT2 ) { // interrupt(s) on PORT2 pending if(IO_INT_STAT & BIT2) { /* interrupt(s) on PORT2 pending */
unsigned long int_stat_f = IO2_INT_STAT_F; // save content unsigned long int_stat_f = IO2_INT_STAT_F; /* save content */
unsigned long int_stat_r = IO2_INT_STAT_R; // save content unsigned long int_stat_r = IO2_INT_STAT_R; /* save content */
IO2_INT_CLR = int_stat_f; // clear flags of fallen pins IO2_INT_CLR = int_stat_f; /* clear flags of fallen pins */
IO2_INT_CLR = int_stat_r; // clear flags of risen pins IO2_INT_CLR = int_stat_r; /* clear flags of risen pins */
test_irq(2, int_stat_f, int_stat_r, gpioint2); test_irq(2, int_stat_f, int_stat_r, gpioint2);
} }
VICVectAddr = 0; // Acknowledge Interrupt
VICVectAddr = 0; /* Acknowledge Interrupt */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** @} */ /** @} */

View File

@ -25,8 +25,8 @@ License. See the file LICENSE in the top level directory for more details.
extern uintptr_t __stack_start; ///< end of user stack memory space extern uintptr_t __stack_start; ///< end of user stack memory space
void lpc2387_pclk_scale(uint32_t source, uint32_t target, uint32_t* pclksel, uint32_t* prescale); void lpc2387_pclk_scale(uint32_t source, uint32_t target, uint32_t *pclksel, uint32_t *prescale);
bool install_irq( int IntNumber, void *HandlerAddr, int Priority ); bool install_irq(int IntNumber, void *HandlerAddr, int Priority);
/** @} */ /** @} */
#endif /* __CPU_H */ #endif /* __CPU_H */

View File

@ -52,15 +52,15 @@ License. See the file LICENSE in the top level directory for more details.
* @see ::rtc_set_alarm, ::rtc_get_alarm * @see ::rtc_set_alarm, ::rtc_get_alarm
*/ */
enum rtc_alarm_mask { enum rtc_alarm_mask {
RTC_AMR_DISABLED = 0, ///< Alarm disables RTC_AMR_DISABLED = 0, ///< Alarm disables
RTC_AMR_SEC = AMRSEC, ///< Alarm mask for Seconds RTC_AMR_SEC = AMRSEC, ///< Alarm mask for Seconds
RTC_AMR_MIN = AMRMIN, ///< Alarm mask for Minutes RTC_AMR_MIN = AMRMIN, ///< Alarm mask for Minutes
RTC_AMR_HOUR= AMRHOUR, ///< Alarm mask for Hours RTC_AMR_HOUR = AMRHOUR, ///< Alarm mask for Hours
RTC_AMR_DOM = AMRDOM, ///< Alarm mask for Day of Month RTC_AMR_DOM = AMRDOM, ///< Alarm mask for Day of Month
RTC_AMR_DOW = AMRDOW, ///< Alarm mask for Day of Week RTC_AMR_DOW = AMRDOW, ///< Alarm mask for Day of Week
RTC_AMR_DOY = AMRDOY, ///< Alarm mask for Day of Year RTC_AMR_DOY = AMRDOY, ///< Alarm mask for Day of Year
RTC_AMR_MON = AMRMON, ///< Alarm mask for Month RTC_AMR_MON = AMRMON, ///< Alarm mask for Month
RTC_AMR_YEAR= AMRYEAR, ///< Alarm mask for Year RTC_AMR_YEAR = AMRYEAR, ///< Alarm mask for Year
}; };
void rtc_reset(void); void rtc_reset(void);
@ -76,7 +76,7 @@ time_t rtc_get_compile_time(void) __attribute__((noinline));
* @param[out] time optional return value * @param[out] time optional return value
* @return clock time in seconds * @return clock time in seconds
*/ */
time_t rtc_time(struct timeval* time); time_t rtc_time(struct timeval *time);
/** /**
* @brief Sets the current clock time * @brief Sets the current clock time
@ -95,7 +95,7 @@ void rtc_set(time_t time);
* *
* @see ::rtc_alarm_mask * @see ::rtc_alarm_mask
*/ */
void rtc_set_alarm(struct tm* localt, enum rtc_alarm_mask mask); void rtc_set_alarm(struct tm *localt, enum rtc_alarm_mask mask);
/** /**
* @brief Gets the current alarm setting * @brief Gets the current alarm setting
@ -106,7 +106,7 @@ void rtc_set_alarm(struct tm* localt, enum rtc_alarm_mask mask);
* @see rtc_set_alarm * @see rtc_set_alarm
* @see ::rtc_alarm_mask * @see ::rtc_alarm_mask
*/ */
enum rtc_alarm_mask _rtc_get_alarm(struct tm* localt); enum rtc_alarm_mask _rtc_get_alarm(struct tm *localt);
/** @} */ /** @} */
#endif /* end __RTC_H */ #endif /* end __RTC_H */

View File

@ -37,105 +37,109 @@ License. See the file LICENSE in the top level directory for more details.
void void
adc_init(void) adc_init(void)
{ {
// enable clock /Power for ADC // enable clock /Power for ADC
PCONP |= BIT12; PCONP |= BIT12;
// peripheral Clock Selection for ADC // peripheral Clock Selection for ADC
PCLKSEL0 |= 0x03000000; // pclock = cclock/8 PCLKSEL0 |= 0x03000000; // pclock = cclock/8
// set A/D control register AD0CR // set A/D control register AD0CR
AD0CR = ( 0x01 << 0 ) | /* SEL=1, select channel 0~7 on ADC0 */ AD0CR = (0x01 << 0) | /* SEL=1, select channel 0~7 on ADC0 */
( 0xff << 8 ) | /* CLKDIV = 1, ADC_CLK = PCLK/10 = 0.45 MHz */ (0xff << 8) | /* CLKDIV = 1, ADC_CLK = PCLK/10 = 0.45 MHz */
( 0 << 16 ) | /* BURST = 0, no BURST, software controlled */ (0 << 16) | /* BURST = 0, no BURST, software controlled */
( 0 << 17 ) | /* CLKS = 0, 11 clocks/10 bits */ (0 << 17) | /* CLKS = 0, 11 clocks/10 bits */
( 1 << 21 ) | /* PDN = 1, normal operation */ (1 << 21) | /* PDN = 1, normal operation */
( 0 << 22 ) | /* TEST1:0 = 00 */ (0 << 22) | /* TEST1:0 = 00 */
( 0 << 24 ) | /* START = 0 A/D conversion stops */ (0 << 24) | /* START = 0 A/D conversion stops */
( 0 << 27 ); /* EDGE = 0 (CAP/MAT signal falling,trigger A/D conversion) */ (0 << 27); /* EDGE = 0 (CAP/MAT signal falling,trigger A/D conversion) */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
adc_init_1(void) adc_init_1(void)
{ {
// enable clock /Power for ADC // enable clock /Power for ADC
PCONP |= BIT12; PCONP |= BIT12;
//PIN0.24 function select AD0.1 //PIN0.24 function select AD0.1
PINSEL1 |= BIT16; PINSEL1 |= BIT16;
// peripheral Clock Selection for ADC // peripheral Clock Selection for ADC
PCLKSEL0 |= 0x03000000; // pclock = cclock/8 PCLKSEL0 |= 0x03000000; // pclock = cclock/8
// set A/D control register AD0CR // set A/D control register AD0CR
AD0CR = ( 0x01 << 0 ) | /* SEL=1, select channel 0~7 on ADC0 */ AD0CR = (0x01 << 0) | /* SEL=1, select channel 0~7 on ADC0 */
( 0x00 << 8 ) | /* CLKDIV = 1, ADC_CLK = PCLK/1 = 4.5 MHz */ (0x00 << 8) | /* CLKDIV = 1, ADC_CLK = PCLK/1 = 4.5 MHz */
( 0 << 16 ) | /* BURST = 0, no BURST, software controlled */ (0 << 16) | /* BURST = 0, no BURST, software controlled */
( 0 << 17 ) | /* CLKS = 0, 11 clocks/10 bits */ (0 << 17) | /* CLKS = 0, 11 clocks/10 bits */
( 1 << 21 ) | /* PDN = 1, normal operation */ (1 << 21) | /* PDN = 1, normal operation */
( 0 << 22 ) | /* TEST1:0 = 00 */ (0 << 22) | /* TEST1:0 = 00 */
( 0 << 24 ) | /* START = 0 A/D conversion stops */ (0 << 24) | /* START = 0 A/D conversion stops */
( 0 << 27 ); /* EDGE = 0 (CAP/MAT signal falling,trigger A/D conversion) */ (0 << 27); /* EDGE = 0 (CAP/MAT signal falling,trigger A/D conversion) */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void adc_init_2(void) void adc_init_2(void)
{ {
// enable clock /Power for ADC // enable clock /Power for ADC
PCONP |= BIT12; PCONP |= BIT12;
// PIN0.23 function select to AD0.0 // PIN0.23 function select to AD0.0
PINSEL1 |= BIT14; PINSEL1 |= BIT14;
// peripheral Clock Selection for ADC // peripheral Clock Selection for ADC
PCLKSEL0 |= 0x03000000; // pclock = cclock/8 PCLKSEL0 |= 0x03000000; // pclock = cclock/8
// set A/D control register AD0CR // set A/D control register AD0CR
AD0CR = ( 0x01 << 0 ) | /* SEL=1, select channel 0 on ADC0 */ AD0CR = (0x01 << 0) | /* SEL=1, select channel 0 on ADC0 */
( 0x00 << 8 ) | /* CLKDIV = 1, ADC_CLK = PCLK/1 = 4.5 MHz */ (0x00 << 8) | /* CLKDIV = 1, ADC_CLK = PCLK/1 = 4.5 MHz */
( 0 << 16 ) | /* BURST = 0, no BURST */ (0 << 16) | /* BURST = 0, no BURST */
( 0 << 17 ) | /* CLKS = 0, 11 clocks/10 bits */ (0 << 17) | /* CLKS = 0, 11 clocks/10 bits */
( 1 << 21 ) | /* PDN = 1, normal operation */ (1 << 21) | /* PDN = 1, normal operation */
( 0 << 22 ) | /* TEST1:0 = 00 */ (0 << 22) | /* TEST1:0 = 00 */
( 0 << 24 ) | /* START = 0 A/D conversion stops */ (0 << 24) | /* START = 0 A/D conversion stops */
( 0 << 27 ); /* EDGE = 0 (CAP/MAT signal falling,trigger A/D conversion) */ (0 << 27); /* EDGE = 0 (CAP/MAT signal falling,trigger A/D conversion) */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uint16_t adc_read(uint8_t channel) uint16_t adc_read(uint8_t channel)
{ {
#ifdef ENABLE_DEBUG #ifdef ENABLE_DEBUG
uint32_t t1, t2; uint32_t t1, t2;
#endif #endif
uint32_t regVal, adc_data; uint32_t regVal, adc_data;
/* channel number is 0 through 7 */
if (channel >= ADC_NUM)
{
channel = 0; /* reset channel number to 0 */
}
/* switch channel, start A/D convert */ /* channel number is 0 through 7 */
AD0CR &= 0xFFFFFF00; if(channel >= ADC_NUM) {
channel = 0; /* reset channel number to 0 */
}
/* switch channel, start A/D convert */
AD0CR &= 0xFFFFFF00;
#ifdef ENABLE_DEBUG #ifdef ENABLE_DEBUG
t1 = hwtimer_now(); t1 = hwtimer_now();
#endif #endif
AD0CR |= (1 << 24) | (1 << channel); AD0CR |= (1 << 24) | (1 << channel);
#ifdef ENABLE_DEBUG #ifdef ENABLE_DEBUG
t2 = hwtimer_now(); t2 = hwtimer_now();
#endif #endif
while (1)
{
/* read result of A/D conversion */
regVal = *(volatile unsigned long *)(AD0_BASE_ADDR + ADC_OFFSET + ADC_INDEX * channel);
/* wait until end of A/D convert */ while(1) {
if (regVal & ADC_DONE) break; /* read result of A/D conversion */
} regVal = *(volatile unsigned long *)(AD0_BASE_ADDR + ADC_OFFSET + ADC_INDEX * channel);
AD0CR &= 0xF8FFFFFF; /* stop ADC now */
if (regVal & ADC_OVERRUN) /* save data when it's not overrun, otherwise, return zero */ /* wait until end of A/D convert */
{ if(regVal & ADC_DONE) {
return 0; break;
} }
adc_data = (regVal >> 6) & 0x3FF; }
DEBUG("%s, %d: %lu\n", __FILE__, __LINE__, t1);
DEBUG("%s, %d: %lu\n", __FILE__, __LINE__, t2); AD0CR &= 0xF8FFFFFF; /* stop ADC now */
return (uint16_t) adc_data; /* return A/D conversion value */
if(regVal & ADC_OVERRUN) { /* save data when it's not overrun, otherwise, return zero */
return 0;
}
adc_data = (regVal >> 6) & 0x3FF;
DEBUG("%s, %d: %lu\n", __FILE__, __LINE__, t1);
DEBUG("%s, %d: %lu\n", __FILE__, __LINE__, t2);
return (uint16_t) adc_data; /* return A/D conversion value */
} }

View File

@ -44,69 +44,82 @@ extern void init_clks2(void);
#define ENABLE_DEBUG 0 #define ENABLE_DEBUG 0
#include <debug.h> #include <debug.h>
void lpm_init(void) { void lpm_init(void)
lpm = LPM_ON; {
lpm = LPM_ON;
} }
#define LPM_DEBUG 1 #define LPM_DEBUG 1
void lpm_begin_awake(void) { void lpm_begin_awake(void)
if (lpm >= LPM_SLEEP ) { // wake up from deep sleep {
init_clks1(); if(lpm >= LPM_SLEEP) { // wake up from deep sleep
} init_clks1();
}
} }
void lpm_end_awake(void) { void lpm_end_awake(void)
if( lpm >= LPM_SLEEP ) { // wake up from deep sleep {
init_clks2(); if(lpm >= LPM_SLEEP) { // wake up from deep sleep
} init_clks2();
lpm = LPM_ON; }
lpm = LPM_ON;
} }
void lpm_awake(void) { void lpm_awake(void)
{
#if LPM_DEBUG #if LPM_DEBUG
unsigned long usec = RTC_CTC; unsigned long usec = RTC_CTC;
#endif #endif
if( lpm >= LPM_SLEEP ) { // wake up from deep sleep
//benchmark if(lpm >= LPM_SLEEP) { // wake up from deep sleep
init_clks1(); /* benchmark */
init_clks2(); init_clks1();
// Debug tests init_clks2();
/* Debug tests */
#if LPM_DEBUG #if LPM_DEBUG
usec = RTC_CTC-usec; usec = RTC_CTC - usec;
DEBUG("Wakeup in %lu usecs\n",usec * 31); DEBUG("Wakeup in %lu usecs\n", usec * 31);
#endif #endif
} }
lpm = LPM_ON;
lpm = LPM_ON;
} }
enum lpm_mode lpm_set(enum lpm_mode target) { enum lpm_mode lpm_set(enum lpm_mode target)
unsigned target_flags; {
enum lpm_mode last_lpm = lpm; unsigned target_flags;
enum lpm_mode last_lpm = lpm;
/* calculate target mcu power mode */ /* calculate target mcu power mode */
if( target == LPM_IDLE ) if(target == LPM_IDLE) {
target_flags = PM_IDLE; target_flags = PM_IDLE;
else if( target == LPM_SLEEP ) }
target_flags = PM_SLEEP; else if(target == LPM_SLEEP) {
else if( target == LPM_POWERDOWN ) target_flags = PM_SLEEP;
target_flags = PM_POWERDOWN; }
else else if(target == LPM_POWERDOWN) {
target_flags = 0; target_flags = PM_POWERDOWN;
}
else {
target_flags = 0;
}
lpm = target; lpm = target;
#if iENABLE_DEBUG #if iENABLE_DEBUG
DEBUG("# LPM power down %u -> %u", lpm, target); DEBUG("# LPM power down %u -> %u", lpm, target);
#endif #endif
PCON |= target_flags; // set target power mode PCON |= target_flags; // set target power mode
return last_lpm; return last_lpm;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
enum lpm_mode enum lpm_mode
lpm_get(void) { lpm_get(void)
return lpm; {
return lpm;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** @} */ /** @} */

View File

@ -2,93 +2,120 @@
#include <flashrom.h> #include <flashrom.h>
#include <iap.h> #include <iap.h>
uint8_t iap_get_sector(uint32_t addr) { uint8_t iap_get_sector(uint32_t addr)
if ((addr >=0x00000000) && (addr <= 0x00000FFF)) { {
if((addr >= 0x00000000) && (addr <= 0x00000FFF)) {
return 0; return 0;
} }
if ((addr >=0x00001000) && (addr <= 0x00001FFF)) {
if((addr >= 0x00001000) && (addr <= 0x00001FFF)) {
return 1; return 1;
} }
if ((addr >=0x00002000) && (addr <= 0x00002FFF)) {
if((addr >= 0x00002000) && (addr <= 0x00002FFF)) {
return 2; return 2;
} }
if ((addr >=0x00003000) && (addr <= 0x00003FFF)) {
if((addr >= 0x00003000) && (addr <= 0x00003FFF)) {
return 3; return 3;
} }
if ((addr >=0x00004000) && (addr <= 0x00004FFF)) {
if((addr >= 0x00004000) && (addr <= 0x00004FFF)) {
return 4; return 4;
} }
if ((addr >=0x00005000) && (addr <= 0x00005FFF)) {
if((addr >= 0x00005000) && (addr <= 0x00005FFF)) {
return 5; return 5;
} }
if ((addr >=0x00006000) && (addr <= 0x00006FFF)) {
if((addr >= 0x00006000) && (addr <= 0x00006FFF)) {
return 6; return 6;
} }
if ((addr >=0x00007000) && (addr <= 0x00007FFF)) {
if((addr >= 0x00007000) && (addr <= 0x00007FFF)) {
return 7; return 7;
} }
if ((addr >=0x00008000) && (addr <= 0x0000FFFF)) { if((addr >= 0x00008000) && (addr <= 0x0000FFFF)) {
return 8; return 8;
} }
if ((addr >=0x00010000) && (addr <= 0x00017FFF)) {
if((addr >= 0x00010000) && (addr <= 0x00017FFF)) {
return 9; return 9;
} }
if ((addr >=0x00018000) && (addr <= 0x0001FFFF)) {
if((addr >= 0x00018000) && (addr <= 0x0001FFFF)) {
return 10; return 10;
} }
if ((addr >=0x00020000) && (addr <= 0x00027FFF)) {
if((addr >= 0x00020000) && (addr <= 0x00027FFF)) {
return 11; return 11;
} }
if ((addr >=0x00028000) && (addr <= 0x0002FFFF)) {
if((addr >= 0x00028000) && (addr <= 0x0002FFFF)) {
return 12; return 12;
} }
if ((addr >=0x00030000) && (addr <= 0x00037FFF)) {
if((addr >= 0x00030000) && (addr <= 0x00037FFF)) {
return 13; return 13;
} }
if ((addr >=0x00038000) && (addr <= 0x0003FFFF)) {
if((addr >= 0x00038000) && (addr <= 0x0003FFFF)) {
return 14; return 14;
} }
if ((addr >=0x00040000) && (addr <= 0x00047FFF)) {
if((addr >= 0x00040000) && (addr <= 0x00047FFF)) {
return 15; return 15;
} }
if ((addr >=0x00048000) && (addr <= 0x0004FFFF)) {
if((addr >= 0x00048000) && (addr <= 0x0004FFFF)) {
return 16; return 16;
} }
if ((addr >=0x00050000) && (addr <= 0x00057FFF)) {
if((addr >= 0x00050000) && (addr <= 0x00057FFF)) {
return 17; return 17;
} }
if ((addr >=0x00058000) && (addr <= 0x0005FFFF)) {
if((addr >= 0x00058000) && (addr <= 0x0005FFFF)) {
return 18; return 18;
} }
if ((addr >=0x00060000) && (addr <= 0x00067FFF)) {
if((addr >= 0x00060000) && (addr <= 0x00067FFF)) {
return 19; return 19;
} }
if ((addr >=0x00068000) && (addr <= 0x0006FFFF)) {
if((addr >= 0x00068000) && (addr <= 0x0006FFFF)) {
return 20; return 20;
} }
if ((addr >=0x00070000) && (addr <= 0x00077FFF)) {
if((addr >= 0x00070000) && (addr <= 0x00077FFF)) {
return 21; return 21;
} }
if ((addr >=0x00078000) && (addr <= 0x00078FFF)) {
if((addr >= 0x00078000) && (addr <= 0x00078FFF)) {
return 22; return 22;
} }
if ((addr >=0x00079000) && (addr <= 0x00079FFF)) {
if((addr >= 0x00079000) && (addr <= 0x00079FFF)) {
return 23; return 23;
} }
if ((addr >=0x0007A000) && (addr <= 0x0007AFFF)) {
if((addr >= 0x0007A000) && (addr <= 0x0007AFFF)) {
return 24; return 24;
} }
if ((addr >=0x0007B000) && (addr <= 0x0007BFFF)) {
if((addr >= 0x0007B000) && (addr <= 0x0007BFFF)) {
return 25; return 25;
} }
if ((addr >=0x0007C000) && (addr <= 0x0007CFFF)) {
if((addr >= 0x0007C000) && (addr <= 0x0007CFFF)) {
return 26; return 26;
} }
if ((addr >=0x0007D000) && (addr <= 0x0007DFFF)) {
if((addr >= 0x0007D000) && (addr <= 0x0007DFFF)) {
return 27; return 27;
} }
/* no valid address within flash */ /* no valid address within flash */
return INVALID_ADDRESS; return INVALID_ADDRESS;
} }

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@ License. See the file LICENSE in the top level directory for more details.
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
// cpu /* cpu */
#include "VIC.h" #include "VIC.h"
#include "lpc2387.h" #include "lpc2387.h"
#include "lpc2387-rtc.h" #include "lpc2387-rtc.h"
@ -49,183 +49,192 @@ static volatile time_t epoch;
* @param[in] localt Pointer to structure with time to set * @param[in] localt Pointer to structure with time to set
*/ */
void void
rtc_set_localtime(struct tm* localt) rtc_set_localtime(struct tm *localt)
{ {
if( localt == NULL ) if(localt == NULL) {
return; return;
}
/* set clock */ /* set clock */
RTC_SEC = localt->tm_sec; RTC_SEC = localt->tm_sec;
RTC_MIN = localt->tm_min; RTC_MIN = localt->tm_min;
RTC_HOUR = localt->tm_hour; RTC_HOUR = localt->tm_hour;
RTC_DOM = localt->tm_mday; RTC_DOM = localt->tm_mday;
RTC_DOW = localt->tm_wday; RTC_DOW = localt->tm_wday;
RTC_DOY = localt->tm_yday; RTC_DOY = localt->tm_yday;
RTC_MONTH = localt->tm_mon + 1; RTC_MONTH = localt->tm_mon + 1;
RTC_YEAR = localt->tm_year; RTC_YEAR = localt->tm_year;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void rtc_set(time_t time) { void rtc_set(time_t time)
struct tm* localt; {
localt = localtime(&time); // convert seconds to broken-down time struct tm *localt;
rtc_set_localtime(localt); localt = localtime(&time); /* convert seconds to broken-down time */
epoch = time - localt->tm_sec - localt->tm_min * 60; rtc_set_localtime(localt);
epoch = time - localt->tm_sec - localt->tm_min * 60;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/// set clock to start of unix epoch //* set clock to start of unix epoch */
void rtc_reset(void) void rtc_reset(void)
{ {
rtc_set(0); rtc_set(0);
epoch = 0; epoch = 0;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
rtc_set_alarm(struct tm* localt, enum rtc_alarm_mask mask) rtc_set_alarm(struct tm *localt, enum rtc_alarm_mask mask)
{ {
if( localt != NULL ) { if(localt != NULL) {
RTC_ALSEC = localt->tm_sec; RTC_ALSEC = localt->tm_sec;
RTC_ALMIN = localt->tm_min; RTC_ALMIN = localt->tm_min;
RTC_ALHOUR = localt->tm_hour; RTC_ALHOUR = localt->tm_hour;
RTC_ALDOM = localt->tm_mday; RTC_ALDOM = localt->tm_mday;
RTC_ALDOW = localt->tm_wday; RTC_ALDOW = localt->tm_wday;
RTC_ALDOY = localt->tm_yday; RTC_ALDOY = localt->tm_yday;
RTC_ALMON = localt->tm_mon + 1; RTC_ALMON = localt->tm_mon + 1;
RTC_ALYEAR = localt->tm_year; RTC_ALYEAR = localt->tm_year;
RTC_AMR = ~mask; // set wich alarm fields to check RTC_AMR = ~mask; /* set wich alarm fields to check */
DEBUG("alarm set %2lu.%2lu.%4lu %2lu:%2lu:%2lu\n", DEBUG("alarm set %2lu.%2lu.%4lu %2lu:%2lu:%2lu\n",
RTC_ALDOM, RTC_ALMON, RTC_ALYEAR, RTC_ALHOUR, RTC_ALMIN, RTC_ALSEC); RTC_ALDOM, RTC_ALMON, RTC_ALYEAR, RTC_ALHOUR, RTC_ALMIN, RTC_ALSEC);
} else { }
RTC_AMR = 0xff; else {
} RTC_AMR = 0xff;
}
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
enum rtc_alarm_mask enum rtc_alarm_mask
rtc_get_alarm(struct tm* localt) rtc_get_alarm(struct tm *localt)
{ {
if( localt != NULL ) { if(localt != NULL) {
localt->tm_sec = RTC_ALSEC; localt->tm_sec = RTC_ALSEC;
localt->tm_min = RTC_ALMIN; localt->tm_min = RTC_ALMIN;
localt->tm_hour = RTC_ALHOUR; localt->tm_hour = RTC_ALHOUR;
localt->tm_mday = RTC_ALDOM; localt->tm_mday = RTC_ALDOM;
localt->tm_wday = RTC_ALDOW; localt->tm_wday = RTC_ALDOW;
localt->tm_yday = RTC_ALDOY; localt->tm_yday = RTC_ALDOY;
localt->tm_mon = RTC_ALMON - 1; localt->tm_mon = RTC_ALMON - 1;
localt->tm_year = RTC_ALYEAR; localt->tm_year = RTC_ALYEAR;
localt->tm_isdst = -1; // not available localt->tm_isdst = -1; /* not available */
} }
return (~RTC_AMR) & 0xff; // return which alarm fields are checked
return (~RTC_AMR) & 0xff; /* return which alarm fields are checked */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void RTC_IRQHandler (void) __attribute__ ((interrupt("IRQ"))); void RTC_IRQHandler(void) __attribute__((interrupt("IRQ")));
void RTC_IRQHandler (void) void RTC_IRQHandler(void)
{ {
lpm_begin_awake(); lpm_begin_awake();
if( RTC_ILR & ILR_RTSSF ) {
// sub second interrupt (does not need flag-clearing)
} else if( RTC_ILR & ILR_RTCCIF ) { if(RTC_ILR & ILR_RTSSF) {
// counter increase interrupt /* sub second interrupt (does not need flag-clearing) */
RTC_ILR |= ILR_RTCCIF;
epoch += 60 * 60; // add 1 hour
} else if( RTC_ILR & ILR_RTCALF ) { }
RTC_ILR |= ILR_RTCALF; else if(RTC_ILR & ILR_RTCCIF) {
RTC_AMR = 0xff; // disable alarm irq /* counter increase interrupt */
DEBUG("Ring\n"); RTC_ILR |= ILR_RTCCIF;
lpm_end_awake(); epoch += 60 * 60; /* add 1 hour */
}
VICVectAddr = 0; // Acknowledge Interrupt }
else if(RTC_ILR & ILR_RTCALF) {
RTC_ILR |= ILR_RTCALF;
RTC_AMR = 0xff; /* disable alarm irq */
DEBUG("Ring\n");
lpm_end_awake();
}
VICVectAddr = 0; /* Acknowledge Interrupt */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void rtc_enable(void) void rtc_enable(void)
{ {
RTC_ILR = (ILR_RTSSF | ILR_RTCCIF | ILR_RTCALF); // clear interrupt flags RTC_ILR = (ILR_RTSSF | ILR_RTCCIF | ILR_RTCALF); /* clear interrupt flags */
RTC_CCR |= CCR_CLKEN; // enable clock RTC_CCR |= CCR_CLKEN; /* enable clock */
install_irq(RTC_INT, &RTC_IRQHandler, IRQP_RTC); // install interrupt handler install_irq(RTC_INT, &RTC_IRQHandler, IRQP_RTC); /* install interrupt handler */
time_t now = rtc_time(NULL); time_t now = rtc_time(NULL);
epoch = now - (now % 3600); epoch = now - (now % 3600);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void rtc_init(void) void rtc_init(void)
{ {
PCONP |= BIT9; PCONP |= BIT9;
RTC_AMR = 0xff; // disable alarm irq RTC_AMR = 0xff; /* disable alarm irq */
RTC_CIIR = IMHOUR; // enable increase irq RTC_CIIR = IMHOUR; /* enable increase irq */
RTC_CISS = 0; // disable subsecond irq RTC_CISS = 0; /* disable subsecond irq */
INTWAKE |= BIT15; // rtc irq wakes up mcu from power down INTWAKE |= BIT15; /* rtc irq wakes up mcu from power down */
RTC_CCR = CCR_CLKSRC; // Clock from external 32 kHz Osc. RTC_CCR = CCR_CLKSRC; /* Clock from external 32 kHz Osc. */
/* initialize clock with valid unix compatible values /* initialize clock with valid unix compatible values
* If RTC_YEAR contains an value larger unix time_t we must reset. */ * If RTC_YEAR contains an value larger unix time_t we must reset. */
if( RTC_YEAR > 2037 ) { if(RTC_YEAR > 2037) {
rtc_reset(); rtc_reset();
} }
DEBUG("%2lu.%2lu.%4lu %2lu:%2lu:%2lu epoch %lu\n", DEBUG("%2lu.%2lu.%4lu %2lu:%2lu:%2lu epoch %lu\n",
RTC_DOM, RTC_MONTH, RTC_YEAR, RTC_HOUR, RTC_MIN, RTC_SEC, RTC_DOM, RTC_MONTH, RTC_YEAR, RTC_HOUR, RTC_MIN, RTC_SEC,
epoch); epoch);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
time_t rtc_time(struct timeval* time) time_t rtc_time(struct timeval *time)
{ {
uint32_t sec; uint32_t sec;
uint32_t usec; uint32_t usec;
uint32_t min; uint32_t min;
usec = (RTC_CTC >> 1); usec = (RTC_CTC >> 1);
sec = RTC_SEC; sec = RTC_SEC;
min = RTC_MIN; min = RTC_MIN;
while (usec != (RTC_CTC>>1) ) {
usec = (RTC_CTC >> 1);
sec = RTC_SEC;
min = RTC_MIN;
}
sec += min * 60; // add number of minutes while(usec != (RTC_CTC >> 1)) {
sec += epoch; // add precalculated epoch in hour granularity usec = (RTC_CTC >> 1);
sec = RTC_SEC;
min = RTC_MIN;
}
if( time != NULL ) { sec += min * 60; /* add number of minutes */
usec = usec * 15625; sec += epoch; /* add precalculated epoch in hour granularity */
usec >>= 9;
time->tv_sec = sec;
time->tv_usec = usec;
}
return sec; if(time != NULL) {
usec = usec * 15625;
usec >>= 9;
time->tv_sec = sec;
time->tv_usec = usec;
}
return sec;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void rtc_disable(void) void rtc_disable(void)
{ {
RTC_CCR &= ~CCR_CLKEN; // disable clock RTC_CCR &= ~CCR_CLKEN; /* disable clock */
install_irq(RTC_INT, NULL, 0); install_irq(RTC_INT, NULL, 0);
RTC_ILR = 0; RTC_ILR = 0;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
rtc_get_localtime(struct tm* localt) rtc_get_localtime(struct tm *localt)
{ {
if( localt != NULL ) { if(localt != NULL) {
localt->tm_sec = RTC_SEC; localt->tm_sec = RTC_SEC;
localt->tm_min = RTC_MIN; localt->tm_min = RTC_MIN;
localt->tm_hour = RTC_HOUR; localt->tm_hour = RTC_HOUR;
localt->tm_mday = RTC_DOM; localt->tm_mday = RTC_DOM;
localt->tm_wday = RTC_DOW; localt->tm_wday = RTC_DOW;
localt->tm_yday = RTC_DOY; localt->tm_yday = RTC_DOY;
localt->tm_mon = RTC_MONTH - 1; localt->tm_mon = RTC_MONTH - 1;
localt->tm_year = RTC_YEAR; localt->tm_year = RTC_YEAR;
localt->tm_isdst = -1; // not available localt->tm_isdst = -1; /* not available */
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void gettimeofday_r(struct _reent *r, struct timeval *ptimeval, struct timezone *ptimezone) void gettimeofday_r(struct _reent *r, struct timeval *ptimeval, struct timezone *ptimezone)
{ {
r->_errno = 0; r->_errno = 0;
if( ptimeval != NULL ) {
rtc_time(ptimeval); if(ptimeval != NULL) {
} rtc_time(ptimeval);
}
} }

View File

@ -1,7 +1,8 @@
#include <atomic.h> #include <atomic.h>
#include <cpu.h> #include <cpu.h>
unsigned int atomic_set_return(unsigned int* val, unsigned int set) { unsigned int atomic_set_return(unsigned int *val, unsigned int set)
{
dINT(); dINT();
unsigned int old_val = *val; unsigned int old_val = *val;
*val = set; *val = set;

View File

@ -10,9 +10,9 @@ This file subject to the terms and conditions of the GNU Lesser General Public
License. See the file LICENSE in the top level directory for more details. License. See the file LICENSE in the top level directory for more details.
*******************************************************************************/ *******************************************************************************/
#ifdef CC430 #ifdef CC430
#include <cc430f6137.h> #include <cc430f6137.h>
#else #else
#include <msp430x16x.h> #include <msp430x16x.h>
#endif #endif
#include "cpu.h" #include "cpu.h"
#include "kernel.h" #include "kernel.h"
@ -23,7 +23,8 @@ volatile int __inISR = 0;
char __isr_stack[MSP430_ISR_STACK_SIZE]; char __isr_stack[MSP430_ISR_STACK_SIZE];
void thread_yield() { void thread_yield()
{
__save_context(); __save_context();
dINT(); dINT();
@ -34,49 +35,8 @@ void thread_yield() {
__restore_context(); __restore_context();
} }
// static void __resume_context () { void cpu_switch_context_exit(void)
// __asm__("mov.w %0,r1" : : "m" (active_thread->sp)); {
//
// __asm__("pop r15");
// __asm__("pop r14");
// __asm__("pop r13");
// __asm__("pop r12");
// __asm__("pop r11");
// __asm__("pop r10");
// __asm__("pop r9");
// __asm__("pop r8");
// __asm__("pop r7");
// __asm__("pop r6");
// __asm__("pop r5");
// __asm__("pop r4");
// }
// static void __resume_
//
// }
//
// void __save_context_isr () {
// __asm__("push r4");
// __asm__("push r5");
// __asm__("push r6");
// __asm__("push r7");
// __asm__("push r8");
// __asm__("push r9");
// __asm__("push r10");
// __asm__("push r11");
// __asm__("push r12");
// __asm__("push r13");
// __asm__("push r14");
// __asm__("push r15");
//
// __asm__("mov.w r1,%0" : "=r" (active_thread->sp));
// }
//
//
// __return_from_isr
void cpu_switch_context_exit(void){
active_thread = sched_threads[0]; active_thread = sched_threads[0];
sched_run(); sched_run();
@ -88,8 +48,8 @@ void cpu_switch_context_exit(void){
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
char *thread_stack_init(void *task_func, void *stack_start, int stack_size) char *thread_stack_init(void *task_func, void *stack_start, int stack_size)
{ {
unsigned short * stk; unsigned short *stk;
stk = (unsigned short *) (stack_start + stack_size); stk = (unsigned short *)(stack_start + stack_size);
*stk = (unsigned short) sched_task_exit; *stk = (unsigned short) sched_task_exit;
--stk; --stk;
@ -98,20 +58,22 @@ char *thread_stack_init(void *task_func, void *stack_start, int stack_size)
--stk; --stk;
/* initial value for SR */ /* initial value for SR */
// unsigned int sr;
// __asm__("mov.w r2,%0" : "=r" (sr));
*stk = GIE; *stk = GIE;
--stk; --stk;
/* Space for registers. */ /* Space for registers. */
for (unsigned int i = 15; i > 4; i--) { for(unsigned int i = 15; i > 4; i--) {
*stk = i; *stk = i;
--stk; --stk;
} }
//stk -= 11; //stk -= 11;
return (char*) stk; return (char *) stk;
} }
int inISR() { return __inISR; } int inISR()
{
return __inISR;
}

View File

@ -10,13 +10,14 @@ static void finish(uint8_t istate);
static inline void busy_wait(void); static inline void busy_wait(void);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uint8_t flashrom_erase(uint8_t *addr) { uint8_t flashrom_erase(uint8_t *addr)
{
uint8_t istate = prepare(); uint8_t istate = prepare();
FCTL3 = FWKEY; /* Lock = 0 */ FCTL3 = FWKEY; /* Lock = 0 */
busy_wait(); busy_wait();
FCTL1 = FWKEY | ERASE; FCTL1 = FWKEY | ERASE;
*addr = 0; /* erase Flash segment */ *addr = 0; /* erase Flash segment */
busy_wait(); busy_wait();
FCTL1 = FWKEY; /* ERASE = 0 */ FCTL1 = FWKEY; /* ERASE = 0 */
FCTL3 = FWKEY | LOCK; FCTL3 = FWKEY | LOCK;
@ -24,24 +25,29 @@ uint8_t flashrom_erase(uint8_t *addr) {
return 1; return 1;
} }
void flashrom_write(uint8_t *dst, uint8_t *src, size_t size) { void flashrom_write(uint8_t *dst, uint8_t *src, size_t size)
{
unsigned int i; unsigned int i;
FCTL3 = FWKEY; /* Lock = 0 */ FCTL3 = FWKEY; /* Lock = 0 */
busy_wait(); busy_wait();
for (i = size; i > 0; i--) {
for(i = size; i > 0; i--) {
FCTL1 = FWKEY | WRT; FCTL1 = FWKEY | WRT;
*dst = *src; /* program Flash word */ *dst = *src; /* program Flash word */
while (!(FCTL3 & WAIT)) {
while(!(FCTL3 & WAIT)) {
nop(); nop();
} }
} }
busy_wait(); busy_wait();
FCTL1 = FWKEY; /* WRT = 0 */ FCTL1 = FWKEY; /* WRT = 0 */
FCTL3 = FWKEY | LOCK; /* Lock = 1 */ FCTL3 = FWKEY | LOCK; /* Lock = 1 */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static uint8_t prepare(void) { static uint8_t prepare(void)
{
uint8_t istate; uint8_t istate;
/* Disable all interrupts. */ /* Disable all interrupts. */
@ -65,14 +71,16 @@ static uint8_t prepare(void) {
return istate; return istate;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void finish(uint8_t istate) { void finish(uint8_t istate)
/* Enable interrupts. */ {
IE1 = ie1; /* Enable interrupts. */
IE2 = ie2; IE1 = ie1;
restoreIRQ(istate); IE2 = ie2;
restoreIRQ(istate);
} }
static inline void busy_wait(void) { static inline void busy_wait(void)
{
/* Wait for BUSY = 0, not needed unless run from RAM */ /* Wait for BUSY = 0, not needed unless run from RAM */
while(FCTL3 & 0x0001) { while(FCTL3 & 0x0001) {
nop(); nop();

View File

@ -23,65 +23,77 @@ License. See the file LICENSE in the top level directory for more details.
void (*int_handler)(int); void (*int_handler)(int);
extern void timerA_init(void); extern void timerA_init(void);
static void TA0_disable_interrupt(short timer) { static void TA0_disable_interrupt(short timer)
{
volatile unsigned int *ptr = &TA0CCTL0 + (timer); volatile unsigned int *ptr = &TA0CCTL0 + (timer);
*ptr &= ~(CCIFG); *ptr &= ~(CCIFG);
*ptr &= ~(CCIE); *ptr &= ~(CCIE);
} }
static void TA0_enable_interrupt(short timer) { static void TA0_enable_interrupt(short timer)
{
volatile unsigned int *ptr = &TA0CCTL0 + (timer); volatile unsigned int *ptr = &TA0CCTL0 + (timer);
*ptr |= CCIE; *ptr |= CCIE;
*ptr &= ~(CCIFG); *ptr &= ~(CCIFG);
} }
static void TA0_set_nostart(unsigned long value, short timer) { static void TA0_set_nostart(unsigned long value, short timer)
{
volatile unsigned int *ptr = &TA0CCR0 + (timer); volatile unsigned int *ptr = &TA0CCR0 + (timer);
*ptr = value; *ptr = value;
} }
static void TA0_set(unsigned long value, short timer) { static void TA0_set(unsigned long value, short timer)
{
DEBUG("Setting timer %u to %lu\n", timer, value); DEBUG("Setting timer %u to %lu\n", timer, value);
TA0_set_nostart(value, timer); TA0_set_nostart(value, timer);
TA0_enable_interrupt(timer); TA0_enable_interrupt(timer);
} }
void TA0_unset(short timer) { void TA0_unset(short timer)
{
volatile unsigned int *ptr = &TA0CCR0 + (timer); volatile unsigned int *ptr = &TA0CCR0 + (timer);
TA0_disable_interrupt(timer); TA0_disable_interrupt(timer);
*ptr = 0; *ptr = 0;
} }
unsigned long hwtimer_arch_now() { unsigned long hwtimer_arch_now()
return TA0R; {
return TA0R;
} }
void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu) { void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu)
{
timerA_init(); timerA_init();
int_handler = handler; int_handler = handler;
} }
void hwtimer_arch_enable_interrupt(void) { void hwtimer_arch_enable_interrupt(void)
for (int i = 0; i < ARCH_MAXTIMERS; i++) { {
for(int i = 0; i < ARCH_MAXTIMERS; i++) {
TA0_enable_interrupt(i); TA0_enable_interrupt(i);
} }
} }
void hwtimer_arch_disable_interrupt(void) { void hwtimer_arch_disable_interrupt(void)
for (int i = 0; i < ARCH_MAXTIMERS; i++) { {
for(int i = 0; i < ARCH_MAXTIMERS; i++) {
TA0_disable_interrupt(i); TA0_disable_interrupt(i);
} }
} }
void hwtimer_arch_set(unsigned long offset, short timer) { void hwtimer_arch_set(unsigned long offset, short timer)
{
unsigned int value = hwtimer_arch_now() + offset; unsigned int value = hwtimer_arch_now() + offset;
hwtimer_arch_set_absolute(value, timer); hwtimer_arch_set_absolute(value, timer);
} }
void hwtimer_arch_set_absolute(unsigned long value, short timer) { void hwtimer_arch_set_absolute(unsigned long value, short timer)
TA0_set(value,timer); {
TA0_set(value, timer);
} }
void hwtimer_arch_unset(short timer) { void hwtimer_arch_unset(short timer)
{
TA0_unset(timer); TA0_unset(timer);
} }

View File

@ -39,7 +39,8 @@ extern char __isr_stack[MSP430_ISR_STACK_SIZE];
//#define eINT() eint() //#define eINT() eint()
//#define dINT() dint() //#define dINT() dint()
inline void __save_context_isr(void) { inline void __save_context_isr(void)
{
__asm__("push r15"); __asm__("push r15");
__asm__("push r14"); __asm__("push r14");
__asm__("push r13"); __asm__("push r13");
@ -53,11 +54,12 @@ inline void __save_context_isr(void) {
__asm__("push r5"); __asm__("push r5");
__asm__("push r4"); __asm__("push r4");
__asm__("mov.w r1,%0" : "=r" (active_thread->sp)); __asm__("mov.w r1,%0" : "=r"(active_thread->sp));
} }
inline void __restore_context_isr(void) { inline void __restore_context_isr(void)
__asm__("mov.w %0,r1" : : "m" (active_thread->sp)); {
__asm__("mov.w %0,r1" : : "m"(active_thread->sp));
__asm__("pop r4"); __asm__("pop r4");
__asm__("pop r5"); __asm__("pop r5");
@ -73,36 +75,46 @@ inline void __restore_context_isr(void) {
__asm__("pop r15"); __asm__("pop r15");
} }
inline void __enter_isr(void) { inline void __enter_isr(void)
{
__save_context_isr(); __save_context_isr();
__asm__("mov.w %0,r1" : : "i" (__isr_stack+MSP430_ISR_STACK_SIZE)); __asm__("mov.w %0,r1" : : "i"(__isr_stack+MSP430_ISR_STACK_SIZE));
__inISR = 1; __inISR = 1;
} }
inline void __exit_isr(void) { inline void __exit_isr(void)
{
__inISR = 0; __inISR = 0;
if (sched_context_switch_request) sched_run();
if(sched_context_switch_request) {
sched_run();
}
__restore_context_isr(); __restore_context_isr();
__asm__("reti"); __asm__("reti");
} }
inline void __save_context(void) { inline void __save_context(void)
{
__asm__("push r2"); /* save SR */ __asm__("push r2"); /* save SR */
__save_context_isr(); __save_context_isr();
} }
inline void __restore_context(void) { inline void __restore_context(void)
{
__restore_context_isr(); __restore_context_isr();
__asm__("reti"); __asm__("reti");
} }
inline void eINT(void) { inline void eINT(void)
// puts("+"); {
// puts("+");
eint(); eint();
} }
inline void dINT(void) { inline void dINT(void)
// puts("-"); {
// puts("-");
dint(); dint();
} }

View File

@ -14,9 +14,9 @@ License. See the file LICENSE in the top level directory for more details.
#define __HWTIMER_CPU_H #define __HWTIMER_CPU_H
#ifdef CC430 #ifdef CC430
#include <cc430f6137.h> #include <cc430f6137.h>
#else #else
#include <msp430x16x.h> #include <msp430x16x.h>
#endif #endif
#include <stdint.h> #include <stdint.h>

View File

@ -1,15 +1,14 @@
#ifndef MSPGCC_TIME_H #ifndef MSPGCC_TIME_H
#define MSPGCC_TIME_H #define MSPGCC_TIME_H
struct tm struct tm {
{ int tm_sec; /* Seconds after the minute [0, 59] */
int tm_sec; // Seconds after the minute [0, 59] int tm_min; /* Minutes after the hour [0, 59] */
int tm_min; // Minutes after the hour [0, 59] int tm_hour; /* Hours since midnight [0, 23] */
int tm_hour; // Hours since midnight [0, 23] int tm_mday; /* Day of the month [1, 31] */
int tm_mday; // Day of the month [1, 31] int tm_mon; /* Months since January [0, 11] */
int tm_mon; // Months since January [0, 11] int tm_year; /* Years since 1900 */
int tm_year; // Years since 1900 int tm_wday; /* Days since Sunday [0, 6] */
int tm_wday; // Days since Sunday [0, 6]
}; };
#endif #endif

View File

@ -1,28 +1,41 @@
#include <irq.h> #include <irq.h>
#ifdef CC430 #ifdef CC430
#include <cc430f6137.h> #include <cc430f6137.h>
#else #else
#include <msp430x16x.h> #include <msp430x16x.h>
#endif #endif
#include <cpu.h> #include <cpu.h>
unsigned int disableIRQ() { unsigned int disableIRQ()
{
unsigned int state; unsigned int state;
__asm__("mov.w r2,%0" : "=r" (state)); __asm__("mov.w r2,%0" : "=r"(state));
state &= GIE; state &= GIE;
if (state) dINT();
if(state) {
dINT();
}
return state; return state;
} }
unsigned int enableIRQ() { unsigned int enableIRQ()
{
unsigned int state; unsigned int state;
__asm__("mov.w r2,%0" : "=r" (state)); __asm__("mov.w r2,%0" : "=r"(state));
state &= GIE; state &= GIE;
if (!state) eINT();
if(!state) {
eINT();
}
return state; return state;
} }
void restoreIRQ(unsigned int state) { void restoreIRQ(unsigned int state)
if (state) eINT(); {
if(state) {
eINT();
}
} }

View File

@ -35,9 +35,9 @@
#include "cpu.h" #include "cpu.h"
#ifdef CC430 #ifdef CC430
#include <cc430f6137.h> #include <cc430f6137.h>
#else #else
#include <msp430x16x.h> #include <msp430x16x.h>
#endif #endif
#include "msp430.h" #include "msp430.h"
@ -46,76 +46,76 @@
static void static void
init_ports(void) init_ports(void)
{ {
/* Turn everything off, device drivers enable what is needed. */ /* Turn everything off, device drivers enable what is needed. */
/* All configured for digital I/O */ /* All configured for digital I/O */
#ifdef P1SEL #ifdef P1SEL
P1SEL = 0; P1SEL = 0;
#endif #endif
#ifdef P2SEL #ifdef P2SEL
P2SEL = 0; P2SEL = 0;
#endif #endif
#ifdef P3SEL #ifdef P3SEL
P3SEL = 0; P3SEL = 0;
#endif #endif
#ifdef P4SEL #ifdef P4SEL
P4SEL = 0; P4SEL = 0;
#endif #endif
#ifdef P5SEL #ifdef P5SEL
P5SEL = 0; P5SEL = 0;
#endif #endif
#ifdef P6SEL #ifdef P6SEL
P6SEL = 0; P6SEL = 0;
#endif #endif
/* All available inputs */ /* All available inputs */
#ifdef P1DIR #ifdef P1DIR
P1DIR = 0; P1DIR = 0;
P1OUT = 0; P1OUT = 0;
#endif #endif
#ifdef P2DIR #ifdef P2DIR
P2DIR = 0; P2DIR = 0;
P2OUT = 0; P2OUT = 0;
#endif #endif
#ifdef P3DIR #ifdef P3DIR
P3DIR = 0; P3DIR = 0;
P3OUT = 0; P3OUT = 0;
#endif #endif
#ifdef P4DIR #ifdef P4DIR
P4DIR = 0; P4DIR = 0;
P4OUT = 0; P4OUT = 0;
#endif #endif
#ifdef P5DIR #ifdef P5DIR
P5DIR = 0; P5DIR = 0;
P5OUT = 0; P5OUT = 0;
#endif #endif
#ifdef P6DIR #ifdef P6DIR
P6DIR = 0; P6DIR = 0;
P6OUT = 0; P6OUT = 0;
#endif #endif
P1IE = 0; P1IE = 0;
P2IE = 0; P2IE = 0;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* msp430-ld may align _end incorrectly. Workaround in cpu_init. */ /* msp430-ld may align _end incorrectly. Workaround in cpu_init. */
extern int _end; /* Not in sys/unistd.h */ extern int _end; /* Not in sys/unistd.h */
static char *cur_break = (char *)&_end; static char *cur_break = (char *) &_end;
void void
msp430_cpu_init(void) msp430_cpu_init(void)
{ {
dint(); dint();
init_ports(); init_ports();
// lpm_init(); // lpm_init();
eint(); eint();
if((uintptr_t)cur_break & 1) { /* Workaround for msp430-ld bug! */ if((uintptr_t)cur_break & 1) { /* Workaround for msp430-ld bug! */
cur_break++; cur_break++;
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#define asmv(arg) __asm__ __volatile__(arg) #define asmv(arg) __asm__ __volatile__(arg)
@ -131,20 +131,22 @@ msp430_cpu_init(void)
*/ */
void *sbrk(int incr) void *sbrk(int incr)
{ {
char *stack_pointer; char *stack_pointer;
asmv("mov r1, %0" : "=r" (stack_pointer)); asmv("mov r1, %0" : "=r"(stack_pointer));
stack_pointer -= STACK_EXTRA; stack_pointer -= STACK_EXTRA;
if(incr > (stack_pointer - cur_break))
return (void *)-1; /* ENOMEM */
void *old_break = cur_break; if(incr > (stack_pointer - cur_break)) {
cur_break += incr; return (void *) - 1; /* ENOMEM */
/* }
* If the stack was never here then [old_break .. cur_break] should
* be filled with zeros. void *old_break = cur_break;
*/ cur_break += incr;
return old_break; /*
* If the stack was never here then [old_break .. cur_break] should
* be filled with zeros.
*/
return old_break;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* /*
@ -153,11 +155,11 @@ void *sbrk(int incr)
int int
splhigh_(void) splhigh_(void)
{ {
/* Clear the GIE (General Interrupt Enable) flag. */ /* Clear the GIE (General Interrupt Enable) flag. */
int sr; int sr;
asmv("mov r2, %0" : "=r" (sr)); asmv("mov r2, %0" : "=r"(sr));
asmv("bic %0, r2" : : "i" (GIE)); asmv("bic %0, r2" : : "i"(GIE));
return sr & GIE; /* Ignore other sr bits. */ return sr & GIE; /* Ignore other sr bits. */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* /*
@ -166,8 +168,8 @@ splhigh_(void)
void void
splx_(int sr) splx_(int sr)
{ {
/* If GIE was set, restore it. */ /* If GIE was set, restore it. */
asmv("bis %0, r2" : : "r" (sr)); asmv("bis %0, r2" : : "r"(sr));
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View File

@ -3,7 +3,8 @@
extern void board_init(void); extern void board_init(void);
__attribute__ ((constructor)) static void startup(void) { __attribute__((constructor)) static void startup(void)
{
/* use putchar so the linker links it in: */ /* use putchar so the linker links it in: */
putchar('\n'); putchar('\n');

View File

@ -10,7 +10,8 @@ static void finish(uint8_t istate);
static inline void busy_wait(void); static inline void busy_wait(void);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uint8_t flashrom_erase(uint8_t *addr) { uint8_t flashrom_erase(uint8_t *addr)
{
uint8_t istate = prepare(); uint8_t istate = prepare();
FCTL3 = FWKEY; /* Lock = 0 */ FCTL3 = FWKEY; /* Lock = 0 */
@ -24,24 +25,29 @@ uint8_t flashrom_erase(uint8_t *addr) {
return 1; return 1;
} }
void flashrom_write(uint8_t *dst, uint8_t *src, size_t size) { void flashrom_write(uint8_t *dst, uint8_t *src, size_t size)
{
unsigned int i; unsigned int i;
FCTL3 = FWKEY; /* Lock = 0 */ FCTL3 = FWKEY; /* Lock = 0 */
busy_wait(); busy_wait();
for (i = size; i > 0; i--) {
for(i = size; i > 0; i--) {
FCTL1 = FWKEY | WRT; FCTL1 = FWKEY | WRT;
*dst = *src; /* program Flash word */ *dst = *src; /* program Flash word */
while (!(FCTL3 & WAIT)) {
while(!(FCTL3 & WAIT)) {
nop(); nop();
} }
} }
busy_wait(); busy_wait();
FCTL1 = FWKEY; /* WRT = 0 */ FCTL1 = FWKEY; /* WRT = 0 */
FCTL3 = FWKEY | LOCK; /* Lock = 1 */ FCTL3 = FWKEY | LOCK; /* Lock = 1 */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static uint8_t prepare(void) { static uint8_t prepare(void)
{
uint8_t istate; uint8_t istate;
/* Disable all interrupts. */ /* Disable all interrupts. */
@ -65,14 +71,16 @@ static uint8_t prepare(void) {
return istate; return istate;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void finish(uint8_t istate) { void finish(uint8_t istate)
/* Enable interrupts. */ {
IE1 = ie1; /* Enable interrupts. */
IE2 = ie2; IE1 = ie1;
restoreIRQ(istate); IE2 = ie2;
restoreIRQ(istate);
} }
static inline void busy_wait(void) { static inline void busy_wait(void)
{
/* Wait for BUSY = 0, not needed unless run from RAM */ /* Wait for BUSY = 0, not needed unless run from RAM */
while(FCTL3 & 0x0001) { while(FCTL3 & 0x0001) {
nop(); nop();

View File

@ -10,22 +10,24 @@ extern void TA0_unset(short timer);
void timerA_init(void) void timerA_init(void)
{ {
ticks = 0; // Set tick counter value to 0 ticks = 0; // Set tick counter value to 0
TA0CTL = TASSEL_1 + TACLR; // Clear the timer counter, set ACLK TA0CTL = TASSEL_1 + TACLR; // Clear the timer counter, set ACLK
TA0CTL &= ~TAIFG; // Clear the IFG TA0CTL &= ~TAIFG; // Clear the IFG
TA0CTL &= ~TAIE; // Clear the IFG TA0CTL &= ~TAIE; // Clear the IFG
volatile unsigned int *ccr = &TA0CCR0; volatile unsigned int *ccr = &TA0CCR0;
volatile unsigned int *ctl = &TA0CCTL0; volatile unsigned int *ctl = &TA0CCTL0;
for (int i = 0; i < ARCH_MAXTIMERS; i++) { for(int i = 0; i < ARCH_MAXTIMERS; i++) {
*ccr = 0; *ccr = 0;
*ctl &= ~(CCIFG); *ctl &= ~(CCIFG);
*ctl &= ~(CCIE); *ctl &= ~(CCIE);
} }
ITA0CTL |= MC_2; ITA0CTL |= MC_2;
} }
interrupt(TIMERA0_VECTOR) __attribute__ ((naked)) timer_isr_ccr0(void) { interrupt(TIMERA0_VECTOR) __attribute__((naked)) timer_isr_ccr0(void)
{
__enter_isr(); __enter_isr();
TA0_unset(0); TA0_unset(0);
@ -34,18 +36,20 @@ interrupt(TIMERA0_VECTOR) __attribute__ ((naked)) timer_isr_ccr0(void) {
__exit_isr(); __exit_isr();
} }
interrupt(TIMERA1_VECTOR) __attribute__ ((naked)) timer_isr(void) { interrupt(TIMERA1_VECTOR) __attribute__((naked)) timer_isr(void)
{
__enter_isr(); __enter_isr();
short taiv = TA0IV; short taiv = TA0IV;
if (taiv & TAIFG) { if(taiv & TAIFG) {
// puts("msp430/hwtimer_cpu TAIFG set!"); // puts("msp430/hwtimer_cpu TAIFG set!");
// TA0CTL &= ~TAIFG; // TA0CTL &= ~TAIFG;
// ticks += 0xFFFF; // ticks += 0xFFFF;
} else { }
else {
short timer = (taiv/2); short timer = (taiv / 2);
TA0_unset(timer); TA0_unset(timer);
int_handler(timer); int_handler(timer);
} }

View File

@ -18,7 +18,7 @@
#include <irq.h> #include <irq.h>
#include <debug.h> #include <debug.h>
unsigned int atomic_set_return(unsigned int* val, unsigned int set) unsigned int atomic_set_return(unsigned int *val, unsigned int set)
{ {
unsigned int old_val; unsigned int old_val;
unsigned int old_state; unsigned int old_state;

View File

@ -27,7 +27,8 @@ static uint8_t native_cc110x_ssp0dr;
uint8_t cc110x_txrx(uint8_t c) uint8_t cc110x_txrx(uint8_t c)
{ {
native_cc110x_ssp0dr = c; native_cc110x_ssp0dr = c;
switch (c) {
switch(c) {
case CC1100_READ_BURST: case CC1100_READ_BURST:
case CC1100_WRITE_BURST: case CC1100_WRITE_BURST:
case CC1100_READ_SINGLE: case CC1100_READ_SINGLE:
@ -35,6 +36,7 @@ uint8_t cc110x_txrx(uint8_t c)
default: default:
warnx("cc110x_txrx (%i): not implemented", c); warnx("cc110x_txrx (%i): not implemented", c);
} }
DEBUG("cc110x_txrx\n"); DEBUG("cc110x_txrx\n");
return native_cc110x_ssp0dr; return native_cc110x_ssp0dr;
} }

View File

@ -56,8 +56,8 @@ static void (*int_handler)(int);
*/ */
void ticks2tv(unsigned long ticks, struct timeval *tp) void ticks2tv(unsigned long ticks, struct timeval *tp)
{ {
tp->tv_sec = ticks / HWTIMER_SPEED; tp->tv_sec = ticks / HWTIMER_SPEED;
tp->tv_usec = (ticks % HWTIMER_SPEED) ; tp->tv_usec = (ticks % HWTIMER_SPEED) ;
} }
/** /**
@ -75,7 +75,7 @@ unsigned long tv2ticks(struct timeval *tp)
unsigned long ts2ticks(struct timespec *tp) unsigned long ts2ticks(struct timespec *tp)
{ {
/* TODO: check for overflow */ /* TODO: check for overflow */
return((tp->tv_sec * HWTIMER_SPEED) + (tp->tv_nsec/1000)); return((tp->tv_sec * HWTIMER_SPEED) + (tp->tv_nsec / 1000));
} }
/** /**
@ -84,34 +84,35 @@ unsigned long ts2ticks(struct timespec *tp)
void schedule_timer(void) void schedule_timer(void)
{ {
int l = next_timer; int l = next_timer;
for (
int i = ((next_timer +1) % ARCH_MAXTIMERS);
i != next_timer;
i = ((i+1) % ARCH_MAXTIMERS)
)
{
if ( native_hwtimer_isset[l] != 1 ) { for(
int i = ((next_timer + 1) % ARCH_MAXTIMERS);
i != next_timer;
i = ((i + 1) % ARCH_MAXTIMERS)
) {
if(native_hwtimer_isset[l] != 1) {
/* make sure we dont compare to garbage in the following /* make sure we dont compare to garbage in the following
* if condition */ * if condition */
l = i; l = i;
} }
if ( if(
( native_hwtimer_isset[i] == 1 ) && (native_hwtimer_isset[i] == 1) &&
( tv2ticks(&(native_hwtimer[i].it_value)) < tv2ticks(&(native_hwtimer[l].it_value)) ) (tv2ticks(&(native_hwtimer[i].it_value)) < tv2ticks(&(native_hwtimer[l].it_value)))
) ) {
{
/* set l to the lowest active time */ /* set l to the lowest active time */
l = i; l = i;
} }
} }
next_timer = l; next_timer = l;
/* l could still point to some unused (garbage) timer if no timers /* l could still point to some unused (garbage) timer if no timers
* are set at all */ * are set at all */
if (native_hwtimer_isset[next_timer] == 1) { if(native_hwtimer_isset[next_timer] == 1) {
if (setitimer(ITIMER_REAL, &native_hwtimer[next_timer], NULL) == -1) { if(setitimer(ITIMER_REAL, &native_hwtimer[next_timer], NULL) == -1) {
err(1, "schedule_timer"); err(1, "schedule_timer");
} }
else { else {
@ -139,7 +140,7 @@ void hwtimer_isr_timer()
native_hwtimer_isset[next_timer] = 0; native_hwtimer_isset[next_timer] = 0;
schedule_timer(); schedule_timer();
if (native_hwtimer_irq[i] == 1) { if(native_hwtimer_irq[i] == 1) {
DEBUG("hwtimer_isr_timer(): calling hwtimer.int_handler(%i)\n", i); DEBUG("hwtimer_isr_timer(): calling hwtimer.int_handler(%i)\n", i);
int_handler(i); int_handler(i);
} }
@ -151,18 +152,22 @@ void hwtimer_isr_timer()
void hwtimer_arch_enable_interrupt(void) void hwtimer_arch_enable_interrupt(void)
{ {
DEBUG("hwtimer_arch_enable_interrupt()\n"); DEBUG("hwtimer_arch_enable_interrupt()\n");
if (register_interrupt(SIGALRM, hwtimer_isr_timer) != 0) {
if(register_interrupt(SIGALRM, hwtimer_isr_timer) != 0) {
DEBUG("darn!\n\n"); DEBUG("darn!\n\n");
} }
return; return;
} }
void hwtimer_arch_disable_interrupt(void) void hwtimer_arch_disable_interrupt(void)
{ {
DEBUG("hwtimer_arch_disable_interrupt()\n"); DEBUG("hwtimer_arch_disable_interrupt()\n");
if (unregister_interrupt(SIGALRM) != 0) {
if(unregister_interrupt(SIGALRM) != 0) {
DEBUG("darn!\n\n"); DEBUG("darn!\n\n");
} }
return; return;
} }
@ -180,17 +185,19 @@ void hwtimer_arch_unset(short timer)
void hwtimer_arch_set(unsigned long offset, short timer) void hwtimer_arch_set(unsigned long offset, short timer)
{ {
DEBUG("hwtimer_arch_set(%li, %i)\n", offset, timer); DEBUG("hwtimer_arch_set(%li, %i)\n", offset, timer);
if (offset < HWTIMERMINOFFSET) {
if(offset < HWTIMERMINOFFSET) {
offset = HWTIMERMINOFFSET; offset = HWTIMERMINOFFSET;
DEBUG("hwtimer_arch_set: offset < MIN, set to: %i\n", offset); DEBUG("hwtimer_arch_set: offset < MIN, set to: %i\n", offset);
} }
native_hwtimer_irq[timer] = 1; native_hwtimer_irq[timer] = 1;
native_hwtimer_isset[timer] = 1; native_hwtimer_isset[timer] = 1;
ticks2tv(offset, &(native_hwtimer[timer].it_value)); ticks2tv(offset, &(native_hwtimer[timer].it_value));
DEBUG("hwtimer_arch_set(): that is %lis %lius from now\n", DEBUG("hwtimer_arch_set(): that is %lis %lius from now\n",
native_hwtimer[timer].it_value.tv_sec, native_hwtimer[timer].it_value.tv_sec,
native_hwtimer[timer].it_value.tv_usec); native_hwtimer[timer].it_value.tv_usec);
schedule_timer(); schedule_timer();
@ -219,9 +226,11 @@ unsigned long hwtimer_arch_now(void)
t.tv_sec = mts.tv_sec; t.tv_sec = mts.tv_sec;
t.tv_nsec = mts.tv_nsec; t.tv_nsec = mts.tv_nsec;
#else #else
if (clock_gettime(CLOCK_MONOTONIC, &t) == -1) {
if(clock_gettime(CLOCK_MONOTONIC, &t) == -1) {
err(1, "hwtimer_arch_now: clock_gettime"); err(1, "hwtimer_arch_now: clock_gettime");
} }
#endif #endif
native_hwtimer_now = ts2ticks(&t); native_hwtimer_now = ts2ticks(&t);
@ -238,7 +247,7 @@ void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu)
hwtimer_arch_disable_interrupt(); hwtimer_arch_disable_interrupt();
int_handler = handler; int_handler = handler;
for (int i = 0; i<ARCH_MAXTIMERS; i++) { for(int i = 0; i < ARCH_MAXTIMERS; i++) {
native_hwtimer_irq[i] = 0; native_hwtimer_irq[i] = 0;
native_hwtimer_isset[i] = 0; native_hwtimer_isset[i] = 0;
native_hwtimer[i].it_interval.tv_sec = 0; native_hwtimer[i].it_interval.tv_sec = 0;

View File

@ -52,18 +52,20 @@ char sigalt_stk[SIGSTKSZ];
void print_thread_sigmask(ucontext_t *cp) void print_thread_sigmask(ucontext_t *cp)
{ {
sigset_t *p = &cp->uc_sigmask; sigset_t *p = &cp->uc_sigmask;
if (sigemptyset(p) == -1) {
if(sigemptyset(p) == -1) {
err(1, "print_thread_sigmask: sigemptyset"); err(1, "print_thread_sigmask: sigemptyset");
} }
for (int i = 1; i<(NSIG); i++) { for(int i = 1; i < (NSIG); i++) {
if (native_irq_handlers[i].func != NULL) { if(native_irq_handlers[i].func != NULL) {
printf("%s: %s\n", printf("%s: %s\n",
strsignal(i), strsignal(i),
(sigismember(&native_sig_set, i) ? "blocked": "unblocked") (sigismember(&native_sig_set, i) ? "blocked" : "unblocked")
); );
} }
if (sigismember(p, i)) {
if(sigismember(p, i)) {
printf("%s: pending\n", strsignal(i)); printf("%s: pending\n", strsignal(i));
} }
} }
@ -74,11 +76,11 @@ void print_sigmasks(void)
ucontext_t *p; ucontext_t *p;
//tcb_t *cb = NULL; //tcb_t *cb = NULL;
for (int i=0; i<MAXTHREADS; i++) { for(int i = 0; i < MAXTHREADS; i++) {
if (sched_threads[i] != NULL) { if(sched_threads[i] != NULL) {
printf("%s:\n", sched_threads[i]->name); printf("%s:\n", sched_threads[i]->name);
//print_thread_sigmask(sched_threads[i]->sp); //print_thread_sigmask(sched_threads[i]->sp);
p = (ucontext_t*)(sched_threads[i]->stack_start); p = (ucontext_t *)(sched_threads[i]->stack_start);
print_thread_sigmask(p); print_thread_sigmask(p);
puts(""); puts("");
} }
@ -89,27 +91,32 @@ void native_print_signals()
{ {
sigset_t p, q; sigset_t p, q;
puts("native signals:\n"); puts("native signals:\n");
if (sigemptyset(&p) == -1) {
if(sigemptyset(&p) == -1) {
err(1, "native_print_signals: sigemptyset"); err(1, "native_print_signals: sigemptyset");
} }
if (sigpending(&p) == -1) {
if(sigpending(&p) == -1) {
err(1, "native_print_signals: sigpending"); err(1, "native_print_signals: sigpending");
} }
if (sigprocmask(SIG_SETMASK, NULL, &q) == -1) {
if(sigprocmask(SIG_SETMASK, NULL, &q) == -1) {
err(1, "native_print_signals(): sigprocmask"); err(1, "native_print_signals(): sigprocmask");
} }
for (int i = 1; i<(NSIG); i++) { for(int i = 1; i < (NSIG); i++) {
if (native_irq_handlers[i].func != NULL || i == SIGUSR1) { if(native_irq_handlers[i].func != NULL || i == SIGUSR1) {
printf("%s: %s in active thread\n", printf("%s: %s in active thread\n",
strsignal(i), strsignal(i),
(sigismember(&native_sig_set, i) ? "blocked": "unblocked") (sigismember(&native_sig_set, i) ? "blocked" : "unblocked")
); );
} }
if (sigismember(&p, i)) {
if(sigismember(&p, i)) {
printf("%s: pending\n", strsignal(i)); printf("%s: pending\n", strsignal(i));
} }
if (sigismember(&q, i)) {
if(sigismember(&q, i)) {
printf("%s: blocked in this context\n", strsignal(i)); printf("%s: blocked in this context\n", strsignal(i));
} }
} }
@ -126,24 +133,29 @@ unsigned disableIRQ(void)
_native_in_syscall = 1; _native_in_syscall = 1;
DEBUG("disableIRQ()\n"); DEBUG("disableIRQ()\n");
if (sigfillset(&mask) == -1) { if(sigfillset(&mask) == -1) {
err(1, "disableIRQ(): sigfillset"); err(1, "disableIRQ(): sigfillset");
} }
if (native_interrupts_enabled == 1) {
if(native_interrupts_enabled == 1) {
DEBUG("sigprocmask(..native_sig_set)\n"); DEBUG("sigprocmask(..native_sig_set)\n");
if (sigprocmask(SIG_SETMASK, &mask, &native_sig_set) == -1) {
if(sigprocmask(SIG_SETMASK, &mask, &native_sig_set) == -1) {
err(1, "disableIRQ(): sigprocmask"); err(1, "disableIRQ(): sigprocmask");
} }
} }
else { else {
DEBUG("sigprocmask()\n"); DEBUG("sigprocmask()\n");
if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1) {
if(sigprocmask(SIG_SETMASK, &mask, NULL) == -1) {
err(1, "disableIRQ(): sigprocmask()"); err(1, "disableIRQ(): sigprocmask()");
} }
} }
prev_state = native_interrupts_enabled; prev_state = native_interrupts_enabled;
native_interrupts_enabled = 0; native_interrupts_enabled = 0;
if (_native_sigpend > 0) {
if(_native_sigpend > 0) {
DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n"); DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n");
_native_in_syscall = 0; _native_in_syscall = 0;
printf("calling swapcontext()\n"); printf("calling swapcontext()\n");
@ -152,6 +164,7 @@ unsigned disableIRQ(void)
else { else {
_native_in_syscall = 0; _native_in_syscall = 0;
} }
DEBUG("disableIRQ(): return\n"); DEBUG("disableIRQ(): return\n");
return prev_state; return prev_state;
@ -167,15 +180,16 @@ unsigned enableIRQ(void)
_native_in_syscall = 1; _native_in_syscall = 1;
DEBUG("enableIRQ()\n"); DEBUG("enableIRQ()\n");
if (sigprocmask(SIG_SETMASK, &native_sig_set, NULL) == -1) { if(sigprocmask(SIG_SETMASK, &native_sig_set, NULL) == -1) {
err(1, "enableIRQ(): sigprocmask()"); err(1, "enableIRQ(): sigprocmask()");
} }
prev_state = native_interrupts_enabled; prev_state = native_interrupts_enabled;
native_interrupts_enabled = 1; native_interrupts_enabled = 1;
//print_sigmasks(); //print_sigmasks();
//native_print_signals(); //native_print_signals();
if (_native_sigpend > 0) { if(_native_sigpend > 0) {
DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n"); DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n");
_native_in_syscall = 0; _native_in_syscall = 0;
printf("calling swapcontext()\n"); printf("calling swapcontext()\n");
@ -184,6 +198,7 @@ unsigned enableIRQ(void)
else { else {
_native_in_syscall = 0; _native_in_syscall = 0;
} }
DEBUG("enableIRQ(): return\n"); DEBUG("enableIRQ(): return\n");
return prev_state; return prev_state;
@ -193,12 +208,13 @@ void restoreIRQ(unsigned state)
{ {
DEBUG("restoreIRQ()\n"); DEBUG("restoreIRQ()\n");
if (state == 1) { if(state == 1) {
enableIRQ(); enableIRQ();
} }
else { else {
disableIRQ(); disableIRQ();
} }
return; return;
} }
@ -226,11 +242,13 @@ int _native_popsig(void)
nleft = sizeof(int); nleft = sizeof(int);
i = 0; i = 0;
while ((nleft>0) && ((nread = read(pipefd[0], &sig + i, nleft)) != -1)) {
while((nleft > 0) && ((nread = read(pipefd[0], &sig + i, nleft)) != -1)) {
i += nread; i += nread;
nleft -= nread; nleft -= nread;
} }
if (nread == -1) {
if(nread == -1) {
err(1, "_native_popsig(): read()"); err(1, "_native_popsig(): read()");
} }
@ -246,16 +264,17 @@ void native_irq_handler()
int sig; int sig;
DEBUG("\n\n\t\tnative_irq_handler\n\n"); DEBUG("\n\n\t\tnative_irq_handler\n\n");
while (_native_sigpend > 0) {
while(_native_sigpend > 0) {
sig = _native_popsig(); sig = _native_popsig();
_native_sigpend--; _native_sigpend--;
if (native_irq_handlers[sig].func != NULL) { if(native_irq_handlers[sig].func != NULL) {
DEBUG("calling interrupt handler for %i\n", sig); DEBUG("calling interrupt handler for %i\n", sig);
native_irq_handlers[sig].func(); native_irq_handlers[sig].func();
} }
else if (sig == SIGUSR1) { else if(sig == SIGUSR1) {
DEBUG("ignoring SIGUSR1\n"); DEBUG("ignoring SIGUSR1\n");
} }
else { else {
@ -263,6 +282,7 @@ void native_irq_handler()
errx(1, "XXX: this should not have happened!\n"); errx(1, "XXX: this should not have happened!\n");
} }
} }
DEBUG("native_irq_handler(): return"); DEBUG("native_irq_handler(): return");
_native_in_isr = 0; _native_in_isr = 0;
cpu_switch_context_exit(); cpu_switch_context_exit();
@ -275,32 +295,34 @@ void native_irq_handler()
void native_isr_entry(int sig, siginfo_t *info, void *context) void native_isr_entry(int sig, siginfo_t *info, void *context)
{ {
DEBUG("\n\n\t\tnative_isr_entry\n\n"); DEBUG("\n\n\t\tnative_isr_entry\n\n");
if (native_interrupts_enabled == 0) {
if(native_interrupts_enabled == 0) {
errx(1, "interrupts are off, but I caught a signal."); errx(1, "interrupts are off, but I caught a signal.");
} }
/* save the signal */ /* save the signal */
if (write(pipefd[1], &sig, sizeof(int)) == -1) { if(write(pipefd[1], &sig, sizeof(int)) == -1) {
err(1, "native_isr_entry(): write()"); err(1, "native_isr_entry(): write()");
} }
_native_sigpend++; _native_sigpend++;
/* indicate irs status */ /* indicate irs status */
makecontext(&native_isr_context, native_irq_handler, 0); makecontext(&native_isr_context, native_irq_handler, 0);
_native_cur_ctx = (ucontext_t*)active_thread->sp; _native_cur_ctx = (ucontext_t *)active_thread->sp;
if (_native_in_syscall == 0) { if(_native_in_syscall == 0) {
_native_in_isr = 1; _native_in_isr = 1;
DEBUG("\n\n\t\treturn to _native_sig_leave_tramp\n\n"); DEBUG("\n\n\t\treturn to _native_sig_leave_tramp\n\n");
#ifdef __MACH__ #ifdef __MACH__
_native_saved_eip = ((ucontext_t*)context)->uc_mcontext->__ss.__eip; _native_saved_eip = ((ucontext_t *)context)->uc_mcontext->__ss.__eip;
((ucontext_t*)context)->uc_mcontext->__ss.__eip = (unsigned int)&_native_sig_leave_tramp; ((ucontext_t *)context)->uc_mcontext->__ss.__eip = (unsigned int)&_native_sig_leave_tramp;
#elif BSD #elif BSD
_native_saved_eip = ((struct sigcontext*)context)->sc_eip; _native_saved_eip = ((struct sigcontext *)context)->sc_eip;
((struct sigcontext*)context)->sc_eip = (unsigned int)&_native_sig_leave_tramp; ((struct sigcontext *)context)->sc_eip = (unsigned int)&_native_sig_leave_tramp;
#else #else
_native_saved_eip = ((ucontext_t*)context)->uc_mcontext.gregs[REG_EIP]; _native_saved_eip = ((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP];
((ucontext_t*)context)->uc_mcontext.gregs[REG_EIP] = (unsigned int)&_native_sig_leave_tramp; ((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP] = (unsigned int)&_native_sig_leave_tramp;
#endif #endif
// TODO: change sigmask? // TODO: change sigmask?
} }
@ -321,22 +343,22 @@ int register_interrupt(int sig, void *handler)
struct sigaction sa; struct sigaction sa;
DEBUG("XXX: register_interrupt()\n"); DEBUG("XXX: register_interrupt()\n");
if (sigdelset(&native_sig_set, sig)) { if(sigdelset(&native_sig_set, sig)) {
err(1, "register_interrupt: sigdelset"); err(1, "register_interrupt: sigdelset");
} }
native_irq_handlers[sig].func = handler; native_irq_handlers[sig].func = handler;
sa.sa_sigaction = (void*) native_isr_entry; sa.sa_sigaction = (void *) native_isr_entry;
/* sa.sa_handler = (void*) native_isr_entry; */ /* sa.sa_handler = (void*) native_isr_entry; */
if (sigemptyset(&sa.sa_mask) == -1) { if(sigemptyset(&sa.sa_mask) == -1) {
err(1, "register_interrupt: sigemptyset"); err(1, "register_interrupt: sigemptyset");
} }
sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
if (sigaction(sig, &sa, NULL)) { if(sigaction(sig, &sa, NULL)) {
err(1, "register_interrupt: sigaction"); err(1, "register_interrupt: sigaction");
} }
@ -354,21 +376,25 @@ int unregister_interrupt(int sig)
struct sigaction sa; struct sigaction sa;
DEBUG("XXX: unregister_interrupt()\n"); DEBUG("XXX: unregister_interrupt()\n");
if (sigaddset(&native_sig_set, sig) == -1) { if(sigaddset(&native_sig_set, sig) == -1) {
err(1, "unregister_interrupt: sigaddset"); err(1, "unregister_interrupt: sigaddset");
} }
native_irq_handlers[sig].func = NULL; native_irq_handlers[sig].func = NULL;
/* sa.sa_sigaction = SIG_IGN; */ /* sa.sa_sigaction = SIG_IGN; */
sa.sa_handler = SIG_IGN; sa.sa_handler = SIG_IGN;
if (sigemptyset(&sa.sa_mask) == -1) {
if(sigemptyset(&sa.sa_mask) == -1) {
err(1, "unregister_interrupt: sigemptyset"); err(1, "unregister_interrupt: sigemptyset");
} }
sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
if (sigaction(sig, &sa, NULL)) { if(sigaction(sig, &sa, NULL)) {
err(1, "unregister_interrupt: sigaction"); err(1, "unregister_interrupt: sigaction");
} }
return 0; return 0;
} }
@ -387,14 +413,16 @@ void native_interrupt_init(void)
native_interrupts_enabled = 1; native_interrupts_enabled = 1;
_native_sigpend = 0; _native_sigpend = 0;
for (int i = 0; i<255; i++) { for(int i = 0; i < 255; i++) {
native_irq_handlers[i].func = NULL; native_irq_handlers[i].func = NULL;
} }
sa.sa_sigaction = (void*) native_isr_entry; sa.sa_sigaction = (void *) native_isr_entry;
if (sigemptyset(&sa.sa_mask) == -1) {
if(sigemptyset(&sa.sa_mask) == -1) {
err(1, "native_interrupt_init: sigemptyset"); err(1, "native_interrupt_init: sigemptyset");
} }
sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
/* /*
@ -402,25 +430,26 @@ void native_interrupt_init(void)
err(1, "native_interrupt_init: sigemptyset"); err(1, "native_interrupt_init: sigemptyset");
} }
*/ */
if (sigprocmask(SIG_SETMASK, NULL, &native_sig_set) == -1) { if(sigprocmask(SIG_SETMASK, NULL, &native_sig_set) == -1) {
err(1, "native_interrupt_init(): sigprocmask"); err(1, "native_interrupt_init(): sigprocmask");
} }
if (sigdelset(&native_sig_set, SIGUSR1) == -1) { if(sigdelset(&native_sig_set, SIGUSR1) == -1) {
err(1, "native_interrupt_init: sigdelset"); err(1, "native_interrupt_init: sigdelset");
} }
if (sigaction(SIGUSR1, &sa, NULL)) { if(sigaction(SIGUSR1, &sa, NULL)) {
err(1, "native_interrupt_init: sigaction"); err(1, "native_interrupt_init: sigaction");
} }
if (getcontext(&native_isr_context) == -1) { if(getcontext(&native_isr_context) == -1) {
err(1, "native_isr_entry(): getcontext()"); err(1, "native_isr_entry(): getcontext()");
} }
if (sigfillset(&(native_isr_context.uc_sigmask)) == -1) { if(sigfillset(&(native_isr_context.uc_sigmask)) == -1) {
err(1, "native_isr_entry(): sigfillset()"); err(1, "native_isr_entry(): sigfillset()");
} }
native_isr_context.uc_stack.ss_sp = __isr_stack; native_isr_context.uc_stack.ss_sp = __isr_stack;
native_isr_context.uc_stack.ss_size = SIGSTKSZ; native_isr_context.uc_stack.ss_size = SIGSTKSZ;
native_isr_context.uc_stack.ss_flags = 0; native_isr_context.uc_stack.ss_flags = 0;
@ -430,14 +459,16 @@ void native_interrupt_init(void)
sigstk.ss_sp = sigalt_stk; sigstk.ss_sp = sigalt_stk;
sigstk.ss_size = SIGSTKSZ; sigstk.ss_size = SIGSTKSZ;
sigstk.ss_flags = 0; sigstk.ss_flags = 0;
if (sigaltstack(&sigstk, NULL) < 0) {
if(sigaltstack(&sigstk, NULL) < 0) {
err(1, "main: sigaltstack"); err(1, "main: sigaltstack");
} }
makecontext(&native_isr_context, native_irq_handler, 0); makecontext(&native_isr_context, native_irq_handler, 0);
_native_in_syscall = 0; _native_in_syscall = 0;
if (pipe(pipefd) == -1) { if(pipe(pipefd) == -1) {
err(1, "native_interrupt_init(): pipe()"); err(1, "native_interrupt_init(): pipe()");
} }

View File

@ -47,21 +47,23 @@ void _native_lpm_sleep()
int retval; int retval;
retval = select(1, &_native_uart_rfds, NULL, NULL, NULL); retval = select(1, &_native_uart_rfds, NULL, NULL, NULL);
DEBUG("_native_lpm_sleep: retval: %i\n", retval); DEBUG("_native_lpm_sleep: retval: %i\n", retval);
if (retval != -1) {
if(retval != -1) {
/* uart ready, handle input */ /* uart ready, handle input */
/* TODO: switch to ISR context */ /* TODO: switch to ISR context */
_native_handle_uart0_input(); _native_handle_uart0_input();
} }
else if (errno != EINTR) { else if(errno != EINTR) {
/* select failed for reason other than signal */ /* select failed for reason other than signal */
err(1, "lpm_set(): select()"); err(1, "lpm_set(): select()");
} }
/* otherwise select was interrupted because of a signal, continue below */ /* otherwise select was interrupted because of a signal, continue below */
#else #else
pause(); pause();
#endif #endif
if (_native_sigpend > 0) { if(_native_sigpend > 0) {
DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n"); DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n");
_native_in_syscall = 0; _native_in_syscall = 0;
_native_in_isr = 1; _native_in_isr = 1;
@ -83,8 +85,7 @@ enum lpm_mode lpm_set(enum lpm_mode target)
last_lpm = native_lpm; last_lpm = native_lpm;
native_lpm = target; native_lpm = target;
switch(native_lpm) /* @contiki :-p */ switch(native_lpm) { /* @contiki :-p */
{
case LPM_ON: case LPM_ON:
break; break;

View File

@ -55,15 +55,15 @@ char *thread_stack_init(void *task_func, void *stack_start, int stacksize)
stk = stack_start; stk = stack_start;
#ifdef NATIVESPONTOP #ifdef NATIVESPONTOP
p = (ucontext_t*)stk; p = (ucontext_t *)stk;
stk += sizeof(ucontext_t)/sizeof(void*); stk += sizeof(ucontext_t) / sizeof(void *);
stacksize -= sizeof(ucontext_t); stacksize -= sizeof(ucontext_t);
#else #else
p = (ucontext_t*)(stk + ((stacksize-sizeof(ucontext_t))/sizeof(void*))); p = (ucontext_t *)(stk + ((stacksize - sizeof(ucontext_t)) / sizeof(void *)));
stacksize -= sizeof(ucontext_t); stacksize -= sizeof(ucontext_t);
#endif #endif
if (getcontext(p) == -1) { if(getcontext(p) == -1) {
err(1, "thread_stack_init(): getcontext()"); err(1, "thread_stack_init(): getcontext()");
} }
@ -71,7 +71,8 @@ char *thread_stack_init(void *task_func, void *stack_start, int stacksize)
p->uc_stack.ss_size = stacksize; p->uc_stack.ss_size = stacksize;
p->uc_stack.ss_flags = 0; p->uc_stack.ss_flags = 0;
p->uc_link = &end_context; p->uc_link = &end_context;
if (sigemptyset(&(p->uc_sigmask)) == -1) {
if(sigemptyset(&(p->uc_sigmask)) == -1) {
err(1, "thread_stack_init(): sigemptyset()"); err(1, "thread_stack_init(): sigemptyset()");
} }
@ -89,9 +90,10 @@ void cpu_switch_context_exit(void)
sched_run(); sched_run();
DEBUG("XXX: cpu_switch_context_exit(): calling setcontext(%s)\n\n", active_thread->name); DEBUG("XXX: cpu_switch_context_exit(): calling setcontext(%s)\n\n", active_thread->name);
ctx = (ucontext_t*)(active_thread->sp); ctx = (ucontext_t *)(active_thread->sp);
eINT(); // XXX: workaround for bug (?) in sched_task_exit eINT(); // XXX: workaround for bug (?) in sched_task_exit
if (setcontext(ctx) == -1) {
if(setcontext(ctx) == -1) {
err(1, "cpu_switch_context_exit(): setcontext():"); err(1, "cpu_switch_context_exit(): setcontext():");
} }
} }
@ -105,14 +107,16 @@ void thread_yield()
DEBUG("thread_yield()\n"); DEBUG("thread_yield()\n");
oc = (ucontext_t*)(active_thread->sp); oc = (ucontext_t *)(active_thread->sp);
sched_run(); sched_run();
nc = (ucontext_t*)(active_thread->sp); nc = (ucontext_t *)(active_thread->sp);
if (nc != oc) {
if(nc != oc) {
DEBUG("thread_yield(): calling swapcontext(%s)\n\n", active_thread->name); DEBUG("thread_yield(): calling swapcontext(%s)\n\n", active_thread->name);
if (swapcontext(oc, nc) == -1) {
if(swapcontext(oc, nc) == -1) {
err(1, "thread_yield(): swapcontext()"); err(1, "thread_yield(): swapcontext()");
} }
} }
@ -123,9 +127,10 @@ void thread_yield()
void native_cpu_init() void native_cpu_init()
{ {
if (getcontext(&end_context) == -1) { if(getcontext(&end_context) == -1) {
err(1, "end_context(): getcontext()"); err(1, "end_context(): getcontext()");
} }
end_context.uc_stack.ss_sp = __isr_stack; end_context.uc_stack.ss_sp = __isr_stack;
end_context.uc_stack.ss_size = SIGSTKSZ; end_context.uc_stack.ss_size = SIGSTKSZ;
end_context.uc_stack.ss_flags = 0; end_context.uc_stack.ss_flags = 0;

View File

@ -45,18 +45,20 @@ void rtc_disable(void)
native_rtc_enabled = 0; native_rtc_enabled = 0;
} }
void rtc_set_localtime(struct tm* localt) void rtc_set_localtime(struct tm *localt)
{ {
DEBUG("rtc_set_localtime()\n"); DEBUG("rtc_set_localtime()\n");
printf("setting time not supported."); printf("setting time not supported.");
} }
void rtc_get_localtime(struct tm* localt) void rtc_get_localtime(struct tm *localt)
{ {
time_t t; time_t t;
if(native_rtc_enabled == 1) { if(native_rtc_enabled == 1) {
t = time(NULL); t = time(NULL);
if (localtime_r(&t, localt) == NULL) {
if(localtime_r(&t, localt) == NULL) {
err(1, "rtc_get_localtime: localtime_r"); err(1, "rtc_get_localtime: localtime_r");
} }
} }

View File

@ -22,7 +22,7 @@ extern void board_init(void);
extern void native_cpu_init(void); extern void native_cpu_init(void);
extern void native_interrupt_init(void); extern void native_interrupt_init(void);
__attribute__ ((constructor)) static void startup(void) __attribute__((constructor)) static void startup(void)
{ {
native_cpu_init(); native_cpu_init();
native_interrupt_init(); native_interrupt_init();