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

@ -27,20 +27,20 @@ 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)
@ -61,7 +61,8 @@ unsigned restoreIRQ(unsigned oldCPSR)
return _cpsr; return _cpsr;
} }
unsigned IRQenabled(void) { unsigned IRQenabled(void)
{
unsigned _cpsr; unsigned _cpsr;
_cpsr = __get_cpsr(); _cpsr = __get_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,16 +31,15 @@ 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; char err;
unsigned intstate; unsigned intstate;
uint8_t sec; uint8_t sec;
//buffer_vic = VICIntEnable; // save interrupt enable
//VICIntEnClr = 0xFFFFFFFF; // clear vic
sec = iap_get_sector((uint32_t) dst); 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;
} }
@ -53,10 +51,9 @@ uint8_t flashrom_write(uint8_t *dst, char *src, size_t size) {
/* prepare sector */ /* prepare sector */
err = prepare_sectors(sec, sec); err = prepare_sectors(sec, sec);
if (err) {
if(err) {
DEBUG("\n-- ERROR: PREPARE_SECTOR_FOR_WRITE_OPERATION: %u\n", err); DEBUG("\n-- ERROR: PREPARE_SECTOR_FOR_WRITE_OPERATION: %u\n", err);
/* set interrupts back and return */
// VICIntEnable = buffer_vic;
return 0; return 0;
} }
/* write flash */ /* write flash */
@ -64,27 +61,23 @@ uint8_t flashrom_write(uint8_t *dst, char *src, size_t size) {
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) { if(err) {
DEBUG("ERROR: COPY_RAM_TO_FLASH: %u\n", 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) {
if(err) {
DEBUG("ERROR: COMPARE: %i (at position %u)\n", err, iap_result[1]); DEBUG("ERROR: COMPARE: %i (at position %u)\n", err, iap_result[1]);
/* set interrupts back and return */
// VICIntEnable = buffer_vic;
return 0; return 0;
} }
else else {
{
DEBUG("Data successfully written!\n"); DEBUG("Data successfully written!\n");
/* set interrupts back and return */
// VICIntEnable = buffer_vic;
return 1; return 1;
} }
} }
@ -92,38 +85,45 @@ uint8_t flashrom_write(uint8_t *dst, char *src, size_t size) {
} }
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 */ /* prepare sector */
if (prepare_sectors(sec, sec)) { if(prepare_sectors(sec, sec)) {
DEBUG("-- ERROR: PREPARE_SECTOR_FOR_WRITE_OPERATION --\n"); DEBUG("-- ERROR: PREPARE_SECTOR_FOR_WRITE_OPERATION --\n");
return 0; 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"); DEBUG("Sector successfully erased.\n");
return 1; return 1;
} }
@ -133,7 +133,8 @@ 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[0] = code; // set command code
iap_command[1] = p1; // set 1st param iap_command[1] = p1; // set 1st param
iap_command[2] = p2; // set 2nd param iap_command[2] = p2; // set 2nd param
@ -165,7 +166,8 @@ 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,7 +199,8 @@ 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,7 +223,8 @@ 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,7 +248,8 @@ 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 %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); 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;
/** @} */ /** @} */
@ -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,64 +5,69 @@
#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; uint8_t statusByte = 0;
uint16_t int_state, gdo_state; 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; statusByte = RF1ASTATB;
while( !(RF1AIFCTL1 & RFSTATIFG) );
while(!(RF1AIFCTL1 & RFSTATIFG));
restoreIRQ(int_state); restoreIRQ(int_state);
} }
return statusByte; 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; unsigned char x;
uint16_t int_state; uint16_t int_state;
@ -76,29 +81,32 @@ uint8_t cc110x_read_reg(uint8_t addr) {
} }
// ************************************************************************************************* /**************************************************************************************************
// @fn cc110x_write_reg * @fn cc110x_write_reg
// @brief Write byte to register. * @brief Write byte to register.
// @param none * @param none
// @return none * @return none
// ************************************************************************************************* **************************************************************************************************/
void cc110x_write_reg(uint8_t addr, uint8_t value) { void cc110x_write_reg(uint8_t addr, uint8_t value)
{
volatile unsigned int i; volatile unsigned int i;
uint16_t int_state; uint16_t int_state;
int_state = disableIRQ(); int_state = disableIRQ();
while (!(RF1AIFCTL1 & RFINSTRIFG)); // Wait for the Radio to be ready for the next instruction while(!(RF1AIFCTL1 & RFINSTRIFG)); /* Wait for the Radio to be ready for the next instruction */
RF1AINSTRW = ((addr | RF_REGWR)<<8 ) + value; // Send address + Instruction RF1AINSTRW = ((addr | RF_REGWR) << 8) + value; /* Send address + Instruction */
while (!(RFDINIFG & RF1AIFCTL1));
i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status byte 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; unsigned int i;
uint16_t int_state; 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 */
/* Also initiates auo-read for next DOUT byte */
} }
buffer[count-1] = RF1ADOUT0B; // Store the last DOUT from Radio Core
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; unsigned int i;
uint16_t int_state; 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 */
/* Also initiates auo-read for next DOUT byte */
} }
buffer[count-1] = RF1ADOUT0B; // Store the last DOUT from Radio Core
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 {
/* Write Burst works wordwise not bytewise - bug known already */
unsigned char i; unsigned char i;
uint16_t int_state; 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 */
while(!(RFDINIFG & RF1AIFCTL1)); /* Wait for TX to finish */
} }
i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status byte
i = RF1ADOUTB; /* Reset RFDOUTIFG flag which contains status byte */
restoreIRQ(int_state); restoreIRQ(int_state);
return count; return count;

View File

@ -44,13 +44,14 @@
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 */ /* Initialize the shared reference module */
REFCTL0 |= REFMSTR + ref + REFON; /* Enable internal reference (1.5V or 2.5V) */ REFCTL0 |= REFMSTR + ref + REFON; /* Enable internal reference (1.5V or 2.5V) */
@ -75,7 +76,8 @@ uint16_t adc12_single_conversion(uint16_t ref, uint16_t sht, uint16_t channel) {
/* Wait until ADC12 has finished */ /* Wait until ADC12 has finished */
hwtimer_wait(5); hwtimer_wait(5);
while (!adc12_data_ready);
while(!adc12_data_ready);
/* Shut down ADC12 */ /* Shut down ADC12 */
ADC12CTL0 &= ~(ADC12ENC | ADC12SC | sht); ADC12CTL0 &= ~(ADC12ENC | ADC12SC | sht);
@ -90,14 +92,16 @@ uint16_t adc12_single_conversion(uint16_t ref, uint16_t sht, uint16_t channel) {
return adc12_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 */
@ -141,6 +145,7 @@ interrupt (ADC12_VECTOR) __attribute__ ((naked)) adc_isr (void) {
default: default:
break; break;
} }
__exit_isr(); __exit_isr();
} }

View File

@ -51,29 +51,34 @@ 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 {
@ -81,7 +86,7 @@ bool gpioint_set(int port, uint32_t bitmask, int flags, fp_irqcb callback) {
} }
} }
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,32 +211,32 @@ 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;

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) { if(localt == NULL) {
return; 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,14 +180,16 @@ 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;
@ -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

@ -21,16 +21,17 @@ void timerA_init(void)
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,17 +39,18 @@ 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);
} }

View File

@ -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 )
{ 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 + Priority*4); vect_addr = (int *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + Priority * 4);
vect_cntl = (int *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + Priority*4); vect_cntl = (int *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + Priority * 4);
*vect_addr = (int)HandlerAddr; /* set interrupt vector */ *vect_addr = (int)HandlerAddr; /* set interrupt vector */
*vect_cntl = IntNumber + BIT5; *vect_cntl = IntNumber + BIT5;
VICIntEnable = 1 << IntNumber; /* Enable Interrupt */ VICIntEnable = 1 << IntNumber; /* Enable Interrupt */
return( true ); 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 ) { }
else if((*prescale % 8) == 0) {
*pclksel = 0; *pclksel = 0;
pclkdiv = 4; pclkdiv = 4;
} else if( (*prescale % 4) == 0 ) { }
else if((*prescale % 4) == 0) {
*pclksel = 2; *pclksel = 2;
pclkdiv = 2; pclkdiv = 2;
} else { }
else {
*pclksel = 1; *pclksel = 1;
pclkdiv = 1; pclkdiv = 1;
} }
*prescale /= pclkdiv; *prescale /= pclkdiv;
if( *prescale % 2 ) if(*prescale % 2) {
(*prescale)++; (*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

@ -42,88 +42,94 @@ 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); restoreIRQ(cpsr);
return true; // success 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

@ -55,12 +55,12 @@ 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

@ -44,14 +44,14 @@ adc_init(void)
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
@ -67,14 +67,14 @@ adc_init_1(void)
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)
@ -89,14 +89,14 @@ void adc_init_2(void)
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)
@ -105,9 +105,9 @@ uint16_t adc_read(uint8_t channel)
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 */ /* channel number is 0 through 7 */
if (channel >= ADC_NUM) if(channel >= ADC_NUM) {
{
channel = 0; /* reset channel number to 0 */ channel = 0; /* reset channel number to 0 */
} }
@ -121,19 +121,23 @@ uint16_t adc_read(uint8_t channel)
#ifdef ENABLE_DEBUG #ifdef ENABLE_DEBUG
t2 = hwtimer_now(); t2 = hwtimer_now();
#endif #endif
while (1)
{ while(1) {
/* read result of A/D conversion */ /* read result of A/D conversion */
regVal = *(volatile unsigned long *)(AD0_BASE_ADDR + ADC_OFFSET + ADC_INDEX * channel); regVal = *(volatile unsigned long *)(AD0_BASE_ADDR + ADC_OFFSET + ADC_INDEX * channel);
/* wait until end of A/D convert */ /* wait until end of A/D convert */
if (regVal & ADC_DONE) break; if(regVal & ADC_DONE) {
break;
} }
}
AD0CR &= 0xF8FFFFFF; /* stop ADC now */ AD0CR &= 0xF8FFFFFF; /* stop ADC now */
if (regVal & ADC_OVERRUN) /* save data when it's not overrun, otherwise, return zero */
{ if(regVal & ADC_OVERRUN) { /* save data when it's not overrun, otherwise, return zero */
return 0; return 0;
} }
adc_data = (regVal >> 6) & 0x3FF; adc_data = (regVal >> 6) & 0x3FF;
DEBUG("%s, %d: %lu\n", __FILE__, __LINE__, t1); DEBUG("%s, %d: %lu\n", __FILE__, __LINE__, t1);
DEBUG("%s, %d: %lu\n", __FILE__, __LINE__, t2); DEBUG("%s, %d: %lu\n", __FILE__, __LINE__, t2);

View File

@ -44,68 +44,81 @@ 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 {
if(lpm >= LPM_SLEEP) { // wake up from deep sleep
init_clks1(); init_clks1();
} }
} }
void lpm_end_awake(void) { void lpm_end_awake(void)
if( lpm >= LPM_SLEEP ) { // wake up from deep sleep {
if(lpm >= LPM_SLEEP) { // wake up from deep sleep
init_clks2(); 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
/* benchmark */
init_clks1(); init_clks1();
init_clks2(); init_clks2();
// Debug tests /* 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; unsigned target_flags;
enum lpm_mode last_lpm = lpm; 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 ) }
else if(target == LPM_SLEEP) {
target_flags = PM_SLEEP; target_flags = PM_SLEEP;
else if( target == LPM_POWERDOWN ) }
else if(target == LPM_POWERDOWN) {
target_flags = PM_POWERDOWN; target_flags = PM_POWERDOWN;
else }
else {
target_flags = 0; 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,90 +2,117 @@
#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;
} }

View File

@ -84,23 +84,24 @@ static volatile DSTATUS Stat = STA_NOINIT; /* Disk status */
static unsigned short CardRCA; /* Assigned RCA */ static unsigned short CardRCA; /* Assigned RCA */
static unsigned char CardType, /* Card type flag */ static unsigned char CardType, /* Card type flag */
CardInfo[16+16+4]; /* CSD(16), CID(16), OCR(4) */ CardInfo[16 + 16 + 4]; /* CSD(16), CID(16), OCR(4) */
static volatile unsigned char XferStat, /* b3:MCI error, b2:Overrun, b1:Write, b0:Read */ static volatile unsigned char XferStat, /* b3:MCI error, b2:Overrun, b1:Write, b0:Read */
XferWc, /* Write block counter */ XferWc, /* Write block counter */
XferWp, XferRp; /* R/W index of block FIFO */ XferWp, XferRp; /* R/W index of block FIFO */
static unsigned long DmaBuff[N_BUF][128] __attribute__ ((section(".usbdata"))); /* Block transfer FIFO */ static unsigned long DmaBuff[N_BUF][128] __attribute__((section(".usbdata"))); /* Block transfer FIFO */
static unsigned long LinkList [N_BUF][4] __attribute__ ((section(".usbdata"))); /* DMA link list */ static unsigned long LinkList [N_BUF][4] __attribute__((section(".usbdata"))); /* DMA link list */
void Isr_MCI (void) __attribute__ ((interrupt("IRQ"))); void Isr_MCI(void) __attribute__((interrupt("IRQ")));
void Isr_GPDMA (void) __attribute__ ((interrupt("IRQ"))); void Isr_GPDMA(void) __attribute__((interrupt("IRQ")));
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Interrupt service routine for data transfer */ /* Interrupt service routine for data transfer */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
void Isr_MCI (void) { void Isr_MCI(void)
{
unsigned long ms; unsigned long ms;
unsigned char n, xs; unsigned char n, xs;
@ -108,18 +109,27 @@ void Isr_MCI (void) {
MCI_CLEAR = ms; MCI_CLEAR = ms;
xs = XferStat; xs = XferStat;
if (ms & 0x400) { /* A block transfer completed (DataBlockEnd) */
if (xs & 1) { /* In card read operation */ if(ms & 0x400) { /* A block transfer completed (DataBlockEnd) */
if (ms & 0x100) /* When last block is received (DataEnd), */ if(xs & 1) { /* In card read operation */
if(ms & 0x100) { /* When last block is received (DataEnd), */
GPDMA_SOFT_BREQ = 0x10; /* Pop off remaining data in the MCIFIFO */ GPDMA_SOFT_BREQ = 0x10; /* Pop off remaining data in the MCIFIFO */
}
n = (XferWp + 1) % N_BUF; /* Next write buffer */ n = (XferWp + 1) % N_BUF; /* Next write buffer */
XferWp = n; XferWp = n;
if (n == XferRp) xs |= 4; /* Check block overrun */
if(n == XferRp) {
xs |= 4; /* Check block overrun */
}
} }
else { /* In card write operation */ else { /* In card write operation */
n = (XferRp + 1) % N_BUF; /* Next read buffer */ n = (XferRp + 1) % N_BUF; /* Next read buffer */
XferRp = n; XferRp = n;
if (n == XferWp) xs |= 4; /* Check block underrun */
if(n == XferWp) {
xs |= 4; /* Check block underrun */
}
} }
} }
else { /* An MCI error occured (not DataBlockEnd) */ else { /* An MCI error occured (not DataBlockEnd) */
@ -131,21 +141,19 @@ void Isr_MCI (void) {
VICVectAddr = 0; VICVectAddr = 0;
} }
void Isr_GPDMA (void) { void Isr_GPDMA(void)
if(GPDMA_INT_TCSTAT & BIT0) {
{ if(GPDMA_INT_TCSTAT & BIT0) {
GPDMA_INT_TCCLR = 0x01; /* Clear GPDMA interrupt flag */ GPDMA_INT_TCCLR = 0x01; /* Clear GPDMA interrupt flag */
if (XferStat & 2)
{ if(XferStat & 2) {
/* In write operation */ /* In write operation */
if (--XferWc == N_BUF) /* Terminate LLI */ if(--XferWc == N_BUF) { /* Terminate LLI */
{
LinkList[XferRp % N_BUF][2] = 0; LinkList[XferRp % N_BUF][2] = 0;
} }
} }
} }
else else {
{
GPDMA_INT_TCCLR = 0x3; GPDMA_INT_TCCLR = 0x3;
} }
@ -161,7 +169,8 @@ void Isr_GPDMA (void) {
* @param blks Number of blocks to receive (1..127) * @param blks Number of blocks to receive (1..127)
* @param bs Block size (64 or 512) * @param bs Block size (64 or 512)
* */ * */
static void ready_reception (unsigned int blks, unsigned int bs) { static void ready_reception(unsigned int blks, unsigned int bs)
{
unsigned int n; unsigned int n;
unsigned long dma_ctrl; unsigned long dma_ctrl;
@ -171,7 +180,7 @@ static void ready_reception (unsigned int blks, unsigned int bs) {
dma_ctrl = 0x88492000 | (bs / 4); /* 1_000_1_0_00_010_010_010_010_************ */ dma_ctrl = 0x88492000 | (bs / 4); /* 1_000_1_0_00_010_010_010_010_************ */
/* Create link list */ /* Create link list */
for (n = 0; n < N_BUF; n++) { for(n = 0; n < N_BUF; n++) {
LinkList[n][0] = (unsigned long)&MCI_FIFO; LinkList[n][0] = (unsigned long)&MCI_FIFO;
LinkList[n][1] = (unsigned long)DmaBuff[n]; LinkList[n][1] = (unsigned long)DmaBuff[n];
LinkList[n][2] = (unsigned long)LinkList[(n + 1) % N_BUF]; LinkList[n][2] = (unsigned long)LinkList[(n + 1) % N_BUF];
@ -189,14 +198,17 @@ static void ready_reception (unsigned int blks, unsigned int bs) {
/* --------- Setting up MCI ---------- */ /* --------- Setting up MCI ---------- */
XferRp = 0; XferWp = 0; /* Block FIFO R/W index */ XferRp = 0;
XferWp = 0; /* Block FIFO R/W index */
XferStat = 1; /* Transfer status: MCI --> Memory */ XferStat = 1; /* Transfer status: MCI --> Memory */
MCI_DATA_LEN = bs * blks; /* Set total data length */ MCI_DATA_LEN = bs * blks; /* Set total data length */
MCI_DATA_TMR = (unsigned long)(MCLK_RW * 0.2); /* Data timer: 0.2sec */ MCI_DATA_TMR = (unsigned long)(MCLK_RW * 0.2); /* Data timer: 0.2sec */
MCI_CLEAR = 0x72A; /* Clear status flags */ MCI_CLEAR = 0x72A; /* Clear status flags */
MCI_MASK0 = 0x72A; /* DataBlockEnd StartBitErr DataEnd RxOverrun DataTimeOut DataCrcFail */ MCI_MASK0 = 0x72A; /* DataBlockEnd StartBitErr DataEnd RxOverrun DataTimeOut DataCrcFail */
for (n = 0; bs > 1; bs >>= 1, n += 0x10);
for(n = 0; bs > 1; bs >>= 1, n += 0x10);
MCI_DATA_CTRL = n | 0xB; /* Start to receive data blocks */ MCI_DATA_CTRL = n | 0xB; /* Start to receive data blocks */
} }
@ -209,7 +221,8 @@ static void ready_reception (unsigned int blks, unsigned int bs) {
/* /*
* @param blks Number of blocks to be transmitted (1..127) * @param blks Number of blocks to be transmitted (1..127)
* */ * */
static void start_transmission ( unsigned char blks) { static void start_transmission(unsigned char blks)
{
unsigned int n; unsigned int n;
unsigned long dma_ctrl; unsigned long dma_ctrl;
@ -221,7 +234,7 @@ static void start_transmission ( unsigned char blks) {
dma_ctrl = 0x84492080; /* 1_000_0_1_00_010_010_010_010_000010000000 */ dma_ctrl = 0x84492080; /* 1_000_0_1_00_010_010_010_010_000010000000 */
/* Create link list */ /* Create link list */
for (n = 0; n < N_BUF; n++) { for(n = 0; n < N_BUF; n++) {
LinkList[n][0] = (unsigned long)DmaBuff[n]; LinkList[n][0] = (unsigned long)DmaBuff[n];
LinkList[n][1] = (unsigned long)&MCI_FIFO; LinkList[n][1] = (unsigned long)&MCI_FIFO;
LinkList[n][2] = (n == blks - 1) ? 0 : (unsigned long)LinkList[(n + 1) % N_BUF]; LinkList[n][2] = (n == blks - 1) ? 0 : (unsigned long)LinkList[(n + 1) % N_BUF];
@ -258,7 +271,8 @@ static void start_transmission ( unsigned char blks) {
/* Stop data transfer */ /* Stop data transfer */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static void stop_transfer (void) { static void stop_transfer(void)
{
MCI_MASK0 = 0; /* Disable MCI interrupt */ MCI_MASK0 = 0; /* Disable MCI interrupt */
MCI_DATA_CTRL = 0; /* Stop MCI data transfer */ MCI_DATA_CTRL = 0; /* Stop MCI data transfer */
@ -272,12 +286,14 @@ static void stop_transfer (void) {
/* Power Control (Device dependent) */ /* Power Control (Device dependent) */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static int power_status (void) { static int power_status(void)
{
return (MCI_POWER & 3) ? 1 : 0; return (MCI_POWER & 3) ? 1 : 0;
} }
static void power_on (void) { static void power_on(void)
{
/* Enable MCI and GPDMA clock */ /* Enable MCI and GPDMA clock */
PCONP |= (3 << 28); PCONP |= (3 << 28);
@ -289,10 +305,10 @@ static void power_on (void) {
PCLKSEL1 = (PCLKSEL1 & 0xFCFFFFFF) | 0x02000000; PCLKSEL1 = (PCLKSEL1 & 0xFCFFFFFF) | 0x02000000;
//0.19 0.20 0.21 0.22 //0.19 0.20 0.21 0.22
PINMODE1 &= ~( (BIT6 | BIT7) | (BIT8 | BIT9) | (BIT10 | BIT11) | (BIT12 | BIT13) ); PINMODE1 &= ~((BIT6 | BIT7) | (BIT8 | BIT9) | (BIT10 | BIT11) | (BIT12 | BIT13));
PINMODE1 |= (BIT7) | (BIT9) | (BIT11) | (BIT13); // no resistors PINMODE1 |= (BIT7) | (BIT9) | (BIT11) | (BIT13); // no resistors
//2.11 2.12 2.13 //2.11 2.12 2.13
PINMODE4 &= ~( (BIT22 | BIT23) | (BIT24 | BIT25) | (BIT26 | BIT27) ); PINMODE4 &= ~((BIT22 | BIT23) | (BIT24 | BIT25) | (BIT26 | BIT27));
PINMODE4 |= (BIT23) | (BIT25) | (BIT27); // no resistors PINMODE4 |= (BIT23) | (BIT25) | (BIT27); // no resistors
/* Attach MCI unit to I/O pad */ /* Attach MCI unit to I/O pad */
PINSEL1 = (PINSEL1 & 0xFFFFC03F) | 0x00002A80; /* MCICLK, MCICMD, MCIDATA0, MCIPWR */ PINSEL1 = (PINSEL1 & 0xFFFFC03F) | 0x00002A80; /* MCICLK, MCICMD, MCIDATA0, MCIPWR */
@ -308,10 +324,10 @@ static void power_on (void) {
/* Register interrupt handlers for MCI,DMA event */ /* Register interrupt handlers for MCI,DMA event */
//RegisterIrq(MCI_INT, Isr_MCI, PRI_LOWEST-1); //RegisterIrq(MCI_INT, Isr_MCI, PRI_LOWEST-1);
install_irq( MCI_INT, (void *)Isr_MCI, 5 ); install_irq(MCI_INT, (void *)Isr_MCI, 5);
//RegisterIrq(GPDMA_INT, Isr_GPDMA, PRI_LOWEST-1); //RegisterIrq(GPDMA_INT, Isr_GPDMA, PRI_LOWEST-1);
install_irq( GPDMA_INT, (void *)Isr_GPDMA, 5 ); install_irq(GPDMA_INT, (void *)Isr_GPDMA, 5);
/* Power-on (VCC is always tied to the socket on this board) */ /* Power-on (VCC is always tied to the socket on this board) */
@ -324,7 +340,8 @@ static void power_on (void) {
} }
static void power_off (void) { static void power_off(void)
{
MCI_MASK0 = 0; MCI_MASK0 = 0;
MCI_COMMAND = 0; MCI_COMMAND = 0;
MCI_DATA_CTRL = 0; MCI_DATA_CTRL = 0;
@ -338,13 +355,13 @@ static void power_off (void) {
//0.21 MCI led Pin (turns sd card off, too) //0.21 MCI led Pin (turns sd card off, too)
//0.19 0.20 0.21 0.22 with pull-down //0.19 0.20 0.21 0.22 with pull-down
PINMODE1 |= (BIT6 | BIT7) | (BIT8 | BIT9) | (BIT10 | BIT11) | (BIT12 | BIT13); PINMODE1 |= (BIT6 | BIT7) | (BIT8 | BIT9) | (BIT10 | BIT11) | (BIT12 | BIT13);
PINSEL1 &= ~( (BIT6 | BIT7) | (BIT8 | BIT9) | (BIT10 | BIT11) | (BIT12 | BIT13) ); PINSEL1 &= ~((BIT6 | BIT7) | (BIT8 | BIT9) | (BIT10 | BIT11) | (BIT12 | BIT13));
// Pins should be now configured as standard input (see board_init.c if you accidentally reconfigured them) // Pins should be now configured as standard input (see board_init.c if you accidentally reconfigured them)
//2.11 2.12 2.13 with pull-down //2.11 2.12 2.13 with pull-down
PINMODE4 |= (BIT22 | BIT23) | (BIT24 | BIT25) | (BIT26 | BIT27); PINMODE4 |= (BIT22 | BIT23) | (BIT24 | BIT25) | (BIT26 | BIT27);
PINSEL4 &= ~( (BIT22 | BIT23) | (BIT24 | BIT25) | (BIT26 | BIT27) ); PINSEL4 &= ~((BIT22 | BIT23) | (BIT24 | BIT25) | (BIT26 | BIT27));
// Pins should be now configured as standard input (see board_init.c if you accidentally reconfigured them) // Pins should be now configured as standard input (see board_init.c if you accidentally reconfigured them)
Stat |= STA_NOINIT; Stat |= STA_NOINIT;
} }
@ -361,62 +378,82 @@ static void power_off (void) {
* @param *buff Response return buffer * @param *buff Response return buffer
* @return 1 when function succeeded otherwise returns 0 * @return 1 when function succeeded otherwise returns 0
* */ * */
static int send_cmd (unsigned int idx, unsigned long arg, unsigned int rt, unsigned long *buff) { static int send_cmd(unsigned int idx, unsigned long arg, unsigned int rt, unsigned long *buff)
{
unsigned int s, mc; unsigned int s, mc;
if (idx & 0x80) { /* Send a CMD55 prior to the specified command if it is ACMD class */ if(idx & 0x80) { /* Send a CMD55 prior to the specified command if it is ACMD class */
if (!send_cmd(CMD55, (unsigned long)CardRCA << 16, 1, buff) /* When CMD55 is faild, */ if(!send_cmd(CMD55, (unsigned long)CardRCA << 16, 1, buff) /* When CMD55 is faild, */
|| !(buff[0] & 0x00000020)) return 0; /* exit with error */ || !(buff[0] & 0x00000020)) {
return 0; /* exit with error */
} }
}
idx &= 0x3F; /* Mask out ACMD flag */ idx &= 0x3F; /* Mask out ACMD flag */
do { /* Wait while CmdActive bit is set */ do { /* Wait while CmdActive bit is set */
MCI_COMMAND = 0; /* Cancel to transmit command */ MCI_COMMAND = 0; /* Cancel to transmit command */
MCI_CLEAR = 0x0C5; /* Clear status flags */ MCI_CLEAR = 0x0C5; /* Clear status flags */
for (s = 0; s < 10; s++) MCI_STATUS; /* Skip lock out time of command reg. */
} while (MCI_STATUS & 0x00800); for(s = 0; s < 10; s++) {
MCI_STATUS; /* Skip lock out time of command reg. */
}
}
while(MCI_STATUS & 0x00800);
MCI_ARGUMENT = arg; /* Set the argument into argument register */ MCI_ARGUMENT = arg; /* Set the argument into argument register */
mc = 0x400 | idx; /* Enable bit + index */ mc = 0x400 | idx; /* Enable bit + index */
if (rt == 1) mc |= 0x040; /* Set Response bit to reveice short resp */
if (rt > 1) mc |= 0x0C0; /* Set Response and LongResp bit to receive long resp */ if(rt == 1) {
mc |= 0x040; /* Set Response bit to reveice short resp */
}
if(rt > 1) {
mc |= 0x0C0; /* Set Response and LongResp bit to receive long resp */
}
MCI_COMMAND = mc; /* Initiate command transaction */ MCI_COMMAND = mc; /* Initiate command transaction */
//Timer[1] = 100; //Timer[1] = 100;
uint32_t timerstart = hwtimer_now(); uint32_t timerstart = hwtimer_now();
for (;;) { /* Wait for end of the cmd/resp transaction */ for(;;) { /* Wait for end of the cmd/resp transaction */
//if (!Timer[1]) return 0; //if (!Timer[1]) return 0;
if(hwtimer_now() - timerstart > 10000) if(hwtimer_now() - timerstart > 10000) {
{
return 0; return 0;
} }
s = MCI_STATUS; /* Get the transaction status */ s = MCI_STATUS; /* Get the transaction status */
if (rt == 0) if(rt == 0) {
{ if(s & 0x080) {
if (s & 0x080)
return 1; /* CmdSent */ return 1; /* CmdSent */
} }
else }
{ else {
if (s & 0x040) if(s & 0x040) {
break; /* CmdRespEnd */ break; /* CmdRespEnd */
if (s & 0x001) }
{ /* CmdCrcFail */
if (idx == 1 || idx == 12 || idx == 41) /* Ignore CRC error on CMD1/12/41 */ if(s & 0x001) {
/* CmdCrcFail */
if(idx == 1 || idx == 12 || idx == 41) { /* Ignore CRC error on CMD1/12/41 */
break; break;
}
return 0; return 0;
} }
if (s & 0x004)
if(s & 0x004) {
return 0; /* CmdTimeOut */ return 0; /* CmdTimeOut */
} }
} }
}
buff[0] = MCI_RESP0; /* Read the response words */ buff[0] = MCI_RESP0; /* Read the response words */
if (rt == 2) {
if(rt == 2) {
buff[1] = MCI_RESP1; buff[1] = MCI_RESP1;
buff[2] = MCI_RESP2; buff[2] = MCI_RESP2;
buff[3] = MCI_RESP3; buff[3] = MCI_RESP3;
@ -436,20 +473,22 @@ static int send_cmd (unsigned int idx, unsigned long arg, unsigned int rt, unsig
* @param tmr Timeout in unit of 1ms * @param tmr Timeout in unit of 1ms
* @returns 1 when card is tran state, otherwise returns 0 * @returns 1 when card is tran state, otherwise returns 0
*/ */
static int wait_ready (unsigned short tmr) { static int wait_ready(unsigned short tmr)
{
unsigned long rc; unsigned long rc;
uint32_t stoppoll = hwtimer_now() + tmr * 100; uint32_t stoppoll = hwtimer_now() + tmr * 100;
bool bBreak = false; bool bBreak = false;
while (hwtimer_now() < stoppoll/*Timer[0]*/)
{ while(hwtimer_now() < stoppoll/*Timer[0]*/) {
if (send_cmd(CMD13, (unsigned long) CardRCA << 16, 1, &rc) && ((rc & 0x01E00) == 0x00800)) if(send_cmd(CMD13, (unsigned long) CardRCA << 16, 1, &rc) && ((rc & 0x01E00) == 0x00800)) {
{
bBreak = true; bBreak = true;
break; break;
} }
/* This loop will take a time. Insert rot_rdq() here for multitask envilonment. */ /* This loop will take a time. Insert rot_rdq() here for multitask envilonment. */
} }
return bBreak;//Timer[0] ? 1 : 0; return bBreak;//Timer[0] ? 1 : 0;
} }
@ -459,7 +498,8 @@ static int wait_ready (unsigned short tmr) {
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Swap byte order */ /* Swap byte order */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static void bswap_cp (unsigned char *dst, const unsigned long *src) { static void bswap_cp(unsigned char *dst, const unsigned long *src)
{
unsigned long d; unsigned long d;
@ -483,19 +523,22 @@ static void bswap_cp (unsigned char *dst, const unsigned long *src) {
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Initialize Disk Drive */ /* Initialize Disk Drive */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
DSTATUS MCI_initialize (void) { DSTATUS MCI_initialize(void)
{
unsigned int cmd, n; unsigned int cmd, n;
unsigned long resp[4]; unsigned long resp[4];
unsigned char ty; unsigned char ty;
if (Stat & STA_NODISK) return Stat; /* No card in the socket */ if(Stat & STA_NODISK) {
return Stat; /* No card in the socket */
}
power_off(); power_off();
hwtimer_wait(HWTIMER_TICKS(1000)); hwtimer_wait(HWTIMER_TICKS(1000));
power_on(); /* Force socket power on */ power_on(); /* Force socket power on */
MCI_CLOCK = 0x100 | (PCLK/MCLK_ID/2-1); /* Set MCICLK = MCLK_ID */ MCI_CLOCK = 0x100 | (PCLK / MCLK_ID / 2 - 1); /* Set MCICLK = MCLK_ID */
//for (Timer[0] = 2; Timer[0]; ); //for (Timer[0] = 2; Timer[0]; );
hwtimer_wait(250); hwtimer_wait(250);
@ -508,22 +551,23 @@ DSTATUS MCI_initialize (void) {
uint32_t start = hwtimer_now(); uint32_t start = hwtimer_now();
/* SDC Ver2 */ /* SDC Ver2 */
if (send_cmd(CMD8, 0x1AA, 1, resp) && (resp[0] & 0xFFF) == 0x1AA) { if(send_cmd(CMD8, 0x1AA, 1, resp) && (resp[0] & 0xFFF) == 0x1AA) {
/* The card can work at vdd range of 2.7-3.6V */ /* The card can work at vdd range of 2.7-3.6V */
DEBUG("SDC Ver. 2\n"); DEBUG("SDC Ver. 2\n");
do { /* Wait while card is busy state (use ACMD41 with HCS bit) */ do { /* Wait while card is busy state (use ACMD41 with HCS bit) */
/* This loop will take a time. Insert wai_tsk(1) here for multitask envilonment. */ /* This loop will take a time. Insert wai_tsk(1) here for multitask envilonment. */
if (hwtimer_now() > start + 1000000/*!Timer[0]*/) { if(hwtimer_now() > start + 1000000/*!Timer[0]*/) {
DEBUG("%s, %d: Timeout #1\n", __FILE__, __LINE__); DEBUG("%s, %d: Timeout #1\n", __FILE__, __LINE__);
goto di_fail; goto di_fail;
} }
} while (!send_cmd(ACMD41, 0x40FF8000, 1, resp) || !(resp[0] & 0x80000000)); }
while(!send_cmd(ACMD41, 0x40FF8000, 1, resp) || !(resp[0] & 0x80000000));
ty = (resp[0] & 0x40000000) ? CT_SD2|CT_BLOCK : CT_SD2; /* Check CCS bit in the OCR */ ty = (resp[0] & 0x40000000) ? CT_SD2 | CT_BLOCK : CT_SD2; /* Check CCS bit in the OCR */
} }
else { /* SDC Ver1 or MMC */ else { /* SDC Ver1 or MMC */
if (send_cmd(ACMD41, 0x00FF8000, 1, resp)) { if(send_cmd(ACMD41, 0x00FF8000, 1, resp)) {
DEBUG("SDC Ver. 1\n"); DEBUG("SDC Ver. 1\n");
ty = CT_SD1; ty = CT_SD1;
cmd = ACMD41; /* ACMD41 is accepted -> SDC Ver1 */ cmd = ACMD41; /* ACMD41 is accepted -> SDC Ver1 */
@ -533,15 +577,18 @@ DSTATUS MCI_initialize (void) {
ty = CT_MMC; ty = CT_MMC;
cmd = CMD1; /* ACMD41 is rejected -> MMC */ cmd = CMD1; /* ACMD41 is rejected -> MMC */
} }
do { /* Wait while card is busy state (use ACMD41 or CMD1) */ do { /* Wait while card is busy state (use ACMD41 or CMD1) */
DEBUG("%s, %d: %lX\n", __FILE__, __LINE__, resp[0]); DEBUG("%s, %d: %lX\n", __FILE__, __LINE__, resp[0]);
/* This loop will take a time. Insert wai_tsk(1) here for multitask envilonment. */ /* This loop will take a time. Insert wai_tsk(1) here for multitask envilonment. */
if (hwtimer_now() > start + 1000000/*!Timer[0]*/) { if(hwtimer_now() > start + 1000000/*!Timer[0]*/) {
DEBUG("now: %lu, started at: %lu\n", hwtimer_now(), start); DEBUG("now: %lu, started at: %lu\n", hwtimer_now(), start);
DEBUG("%s, %d: Timeout #2\n", __FILE__, __LINE__); DEBUG("%s, %d: Timeout #2\n", __FILE__, __LINE__);
goto di_fail; goto di_fail;
} }
} while (!send_cmd(cmd, 0x00FF8000, 1, resp) || !(resp[0] & 0x80000000)); }
while(!send_cmd(cmd, 0x00FF8000, 1, resp) || !(resp[0] & 0x80000000));
} }
CardType = ty; /* Save card type */ CardType = ty; /* Save card type */
@ -549,62 +596,72 @@ DSTATUS MCI_initialize (void) {
/*---- Card is 'ready' state ----*/ /*---- Card is 'ready' state ----*/
if (!send_cmd(CMD2, 0, 2, resp)) { if(!send_cmd(CMD2, 0, 2, resp)) {
DEBUG("%s, %d: Failed entering ident state", __FILE__, __LINE__); DEBUG("%s, %d: Failed entering ident state", __FILE__, __LINE__);
goto di_fail; /* Enter ident state */ goto di_fail; /* Enter ident state */
} }
for (n = 0; n < 4; n++) bswap_cp(&CardInfo[n * 4 + 16], &resp[n]); /* Save CID */
for(n = 0; n < 4; n++) {
bswap_cp(&CardInfo[n * 4 + 16], &resp[n]); /* Save CID */
}
/*---- Card is 'ident' state ----*/ /*---- Card is 'ident' state ----*/
if (ty & CT_SDC) { /* SDC: Get generated RCA and save it */ if(ty & CT_SDC) { /* SDC: Get generated RCA and save it */
if (!send_cmd(CMD3, 0, 1, resp)) { if(!send_cmd(CMD3, 0, 1, resp)) {
DEBUG("%s, %d: Failed generating RCA\n", __FILE__, __LINE__); DEBUG("%s, %d: Failed generating RCA\n", __FILE__, __LINE__);
goto di_fail; goto di_fail;
} }
CardRCA = (unsigned short)(resp[0] >> 16); CardRCA = (unsigned short)(resp[0] >> 16);
} else { /* MMC: Assign RCA to the card */ }
if (!send_cmd(CMD3, 1 << 16, 1, resp)) goto di_fail; else { /* MMC: Assign RCA to the card */
if(!send_cmd(CMD3, 1 << 16, 1, resp)) {
goto di_fail;
}
CardRCA = 1; CardRCA = 1;
} }
/*---- Card is 'stby' state ----*/ /*---- Card is 'stby' state ----*/
if (!send_cmd(CMD9, (unsigned long)CardRCA << 16, 2, resp)) /* Get CSD and save it */ if(!send_cmd(CMD9, (unsigned long)CardRCA << 16, 2, resp)) { /* Get CSD and save it */
{
goto di_fail; goto di_fail;
} }
for (n = 0; n < 4; n++) bswap_cp(&CardInfo[n * 4], &resp[n]);
if (!send_cmd(CMD7, (unsigned long)CardRCA << 16, 1, resp)) /* Select card */ for(n = 0; n < 4; n++) {
{ bswap_cp(&CardInfo[n * 4], &resp[n]);
}
if(!send_cmd(CMD7, (unsigned long)CardRCA << 16, 1, resp)) { /* Select card */
//printf("MCI CMD7 fail\n"); //printf("MCI CMD7 fail\n");
goto di_fail; goto di_fail;
} }
/*---- Card is 'tran' state ----*/ /*---- Card is 'tran' state ----*/
if (!(ty & CT_BLOCK)) { /* Set data block length to 512 (for byte addressing cards) */ if(!(ty & CT_BLOCK)) { /* Set data block length to 512 (for byte addressing cards) */
if (!send_cmd(CMD16, 512, 1, resp) || (resp[0] & 0xFDF90000)) if(!send_cmd(CMD16, 512, 1, resp) || (resp[0] & 0xFDF90000)) {
{
//printf("MCI CMD16 fail\n"); //printf("MCI CMD16 fail\n");
goto di_fail; goto di_fail;
} }
} }
#if USE_4BIT #if USE_4BIT
if (ty & CT_SDC) { /* Set wide bus mode (for SDCs) */
if (!send_cmd(ACMD6, 2, 1, resp) /* Set bus mode of SDC */ if(ty & CT_SDC) { /* Set wide bus mode (for SDCs) */
|| (resp[0] & 0xFDF90000)) if(!send_cmd(ACMD6, 2, 1, resp) /* Set bus mode of SDC */
{ || (resp[0] & 0xFDF90000)) {
//printf("MCI ACMD6 fail\n"); //printf("MCI ACMD6 fail\n");
goto di_fail; goto di_fail;
} }
MCI_CLOCK |= 0x800; /* Set bus mode of MCI */ MCI_CLOCK |= 0x800; /* Set bus mode of MCI */
} }
#endif #endif
MCI_CLOCK = (MCI_CLOCK & 0xF00) | 0x200 | (PCLK/MCLK_RW/2-1); /* Set MCICLK = MCLK_RW, power-save mode */ MCI_CLOCK = (MCI_CLOCK & 0xF00) | 0x200 | (PCLK / MCLK_RW / 2 - 1); /* Set MCICLK = MCLK_RW, power-save mode */
Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */ Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */
return Stat; return Stat;
@ -622,7 +679,8 @@ di_fail:
/* Get Disk Status */ /* Get Disk Status */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
DSTATUS MCI_status (void) { DSTATUS MCI_status(void)
{
return Stat; return Stat;
} }
@ -638,50 +696,63 @@ DSTATUS MCI_status (void) {
* @param sector Start sector number (LBA) * @param sector Start sector number (LBA)
* @param count Sector count (1..127) * @param count Sector count (1..127)
*/ */
DRESULT MCI_read (unsigned char *buff, unsigned long sector, unsigned char count) { DRESULT MCI_read(unsigned char *buff, unsigned long sector, unsigned char count)
{
unsigned long resp; unsigned long resp;
unsigned int cmd; unsigned int cmd;
unsigned char rp; unsigned char rp;
if (count < 1 || count > 127) return RES_PARERR; /* Check parameter */ if(count < 1 || count > 127) {
if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check drive status */ return RES_PARERR; /* Check parameter */
}
if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert LBA to byte address if needed */ if(Stat & STA_NOINIT) {
if (!wait_ready(500)) return RES_ERROR; /* Make sure that card is tran state */ return RES_NOTRDY; /* Check drive status */
}
if(!(CardType & CT_BLOCK)) {
sector *= 512; /* Convert LBA to byte address if needed */
}
if(!wait_ready(500)) {
return RES_ERROR; /* Make sure that card is tran state */
}
ready_reception(count, 512); /* Ready to receive data blocks */ ready_reception(count, 512); /* Ready to receive data blocks */
cmd = (count > 1) ? CMD18 : CMD17; /* Transfer type: Single block or Multiple block */ cmd = (count > 1) ? CMD18 : CMD17; /* Transfer type: Single block or Multiple block */
if (send_cmd(cmd, sector, 1, &resp) /* Start to read */ if(send_cmd(cmd, sector, 1, &resp) /* Start to read */
&& !(resp & 0xC0580000)) && !(resp & 0xC0580000)) {
{
rp = 0; rp = 0;
do
{ do {
while ((rp == XferWp) && !(XferStat & 0xC)) while((rp == XferWp) && !(XferStat & 0xC)) {
{ /* Wait for block arrival */ /* Wait for block arrival */
/* This loop will take a time. Replace it with sync process for multitask envilonment. */ /* This loop will take a time. Replace it with sync process for multitask envilonment. */
} }
if (XferStat & 0xC)
{ if(XferStat & 0xC) {
break; /* Abort if any error has occured */ break; /* Abort if any error has occured */
} }
Copy_al2un(buff, DmaBuff[rp], 512); /* Pop an block */ Copy_al2un(buff, DmaBuff[rp], 512); /* Pop an block */
XferRp = rp = (rp + 1) % N_BUF; /* Next DMA buffer */ XferRp = rp = (rp + 1) % N_BUF; /* Next DMA buffer */
if (XferStat & 0xC)
{ if(XferStat & 0xC) {
break; /* Abort if overrun has occured */ break; /* Abort if overrun has occured */
} }
buff += 512; /* Next user buffer address */ buff += 512; /* Next user buffer address */
} }
while (--count); while(--count);
if (cmd == CMD18) /* Terminate to read (MB) */
if(cmd == CMD18) { /* Terminate to read (MB) */
send_cmd(CMD12, 0, 1, &resp); send_cmd(CMD12, 0, 1, &resp);
} }
}
stop_transfer(); /* Close data path */ stop_transfer(); /* Close data path */
@ -700,64 +771,96 @@ DRESULT MCI_read (unsigned char *buff, unsigned long sector, unsigned char count
* @param sector Start sector number (LBA) * @param sector Start sector number (LBA)
* @param count Sector count (1..127) * @param count Sector count (1..127)
* */ * */
DRESULT MCI_write (const unsigned char *buff, unsigned long sector, unsigned char count) { DRESULT MCI_write(const unsigned char *buff, unsigned long sector, unsigned char count)
{
unsigned long rc; unsigned long rc;
unsigned int cmd; unsigned int cmd;
unsigned char wp, xc; unsigned char wp, xc;
if (count < 1 || count > 127) return RES_PARERR; /* Check parameter */ if(count < 1 || count > 127) {
if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check drive status */ return RES_PARERR; /* Check parameter */
if (Stat & STA_PROTECT) return RES_WRPRT; /* Check write protection */ }
if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert LBA to byte address if needed */ if(Stat & STA_NOINIT) {
if (!wait_ready(500)) return RES_ERROR; /* Make sure that card is tran state */ return RES_NOTRDY; /* Check drive status */
}
if (count == 1) { /* Single block write */ if(Stat & STA_PROTECT) {
return RES_WRPRT; /* Check write protection */
}
if(!(CardType & CT_BLOCK)) {
sector *= 512; /* Convert LBA to byte address if needed */
}
if(!wait_ready(500)) {
return RES_ERROR; /* Make sure that card is tran state */
}
if(count == 1) { /* Single block write */
cmd = CMD24; cmd = CMD24;
} }
else { /* Multiple block write */ else { /* Multiple block write */
cmd = (CardType & CT_SDC) ? ACMD23 : CMD23; cmd = (CardType & CT_SDC) ? ACMD23 : CMD23;
if (!send_cmd(cmd, count, 1, &rc) /* Preset number of blocks to write */
if(!send_cmd(cmd, count, 1, &rc) /* Preset number of blocks to write */
|| (rc & 0xC0580000)) { || (rc & 0xC0580000)) {
return RES_ERROR; return RES_ERROR;
} }
cmd = CMD25; cmd = CMD25;
} }
if (!send_cmd(cmd, sector, 1, &rc) /* Send a write command */ if(!send_cmd(cmd, sector, 1, &rc) /* Send a write command */
|| (rc & 0xC0580000)) { || (rc & 0xC0580000)) {
return RES_ERROR; return RES_ERROR;
} }
wp = 0; wp = 0;
xc = count; xc = count;
do { /* Fill block FIFO */ do { /* Fill block FIFO */
Copy_un2al(DmaBuff[wp], (unsigned char*)(unsigned int)buff, 512); /* Push a block */ Copy_un2al(DmaBuff[wp], (unsigned char *)(unsigned int)buff, 512); /* Push a block */
wp++; /* Next DMA buffer */ wp++; /* Next DMA buffer */
count--; count--;
buff += 512; /* Next user buffer address */ buff += 512; /* Next user buffer address */
} while (count && wp < N_BUF); }
while(count && wp < N_BUF);
XferWp = wp = wp % N_BUF; XferWp = wp = wp % N_BUF;
start_transmission(xc); /* Start transmission */ start_transmission(xc); /* Start transmission */
while (count) { while(count) {
while((wp == XferRp) && !(XferStat & 0xC)) { /* Wait for block FIFO not full */ while((wp == XferRp) && !(XferStat & 0xC)) { /* Wait for block FIFO not full */
/* This loop will take a time. Replace it with sync process for multitask envilonment. */ /* This loop will take a time. Replace it with sync process for multitask envilonment. */
} }
if (XferStat & 0xC) break; /* Abort if block underrun or any MCI error has occured */
Copy_un2al(DmaBuff[wp], (unsigned char*)(unsigned int)buff, 512); /* Push a block */ if(XferStat & 0xC) {
break; /* Abort if block underrun or any MCI error has occured */
}
Copy_un2al(DmaBuff[wp], (unsigned char *)(unsigned int)buff, 512); /* Push a block */
XferWp = wp = (wp + 1) % N_BUF; /* Next DMA buffer */ XferWp = wp = (wp + 1) % N_BUF; /* Next DMA buffer */
if (XferStat & 0xC) break; /* Abort if block underrun has occured */
if(XferStat & 0xC) {
break; /* Abort if block underrun has occured */
}
count--; count--;
buff += 512; /* Next user buffer address */ buff += 512; /* Next user buffer address */
} }
while (!(XferStat & 0xC)); /* Wait for all blocks sent (block underrun) */ while(!(XferStat & 0xC)); /* Wait for all blocks sent (block underrun) */
if (XferStat & 0x8) count = 1; /* Abort if any MCI error has occured */
if(XferStat & 0x8) {
count = 1; /* Abort if any MCI error has occured */
}
stop_transfer(); /* Close data path */ stop_transfer(); /* Close data path */
if (cmd == CMD25 && (CardType & CT_SDC)) /* Terminate to write (SDC w/MB) */
if(cmd == CMD25 && (CardType & CT_SDC)) { /* Terminate to write (SDC w/MB) */
send_cmd(CMD12, 0, 1, &rc); send_cmd(CMD12, 0, 1, &rc);
}
return count ? RES_ERROR : RES_OK; return count ? RES_ERROR : RES_OK;
} }
@ -770,7 +873,7 @@ DRESULT MCI_write (const unsigned char *buff, unsigned long sector, unsigned cha
/* Miscellaneous Functions */ /* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
DRESULT MCI_ioctl ( DRESULT MCI_ioctl(
unsigned char ctrl, /* Control code */ unsigned char ctrl, /* Control code */
void *buff /* Buffer to send/receive data block */ void *buff /* Buffer to send/receive data block */
) )
@ -780,68 +883,91 @@ DRESULT MCI_ioctl (
unsigned long resp[4], d, *dp, st, ed; unsigned long resp[4], d, *dp, st, ed;
if (Stat & STA_NOINIT) return RES_NOTRDY; if(Stat & STA_NOINIT) {
return RES_NOTRDY;
}
res = RES_ERROR; res = RES_ERROR;
switch (ctrl) { switch(ctrl) {
case CTRL_SYNC : /* Make sure that all data has been written on the media */ case CTRL_SYNC : /* Make sure that all data has been written on the media */
if (wait_ready(500)) /* Wait for card enters tarn state */ if(wait_ready(500)) { /* Wait for card enters tarn state */
res = RES_OK; res = RES_OK;
}
break; break;
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (unsigned long) */ case GET_SECTOR_COUNT : /* Get number of sectors on the disk (unsigned long) */
if ((CardInfo[0] >> 6) == 1) { /* SDC CSD v2.0 */ if((CardInfo[0] >> 6) == 1) { /* SDC CSD v2.0 */
d = ((unsigned short)CardInfo[8] << 8) + CardInfo[9] + 1; d = ((unsigned short)CardInfo[8] << 8) + CardInfo[9] + 1;
*(unsigned long*)buff = d << 10; *(unsigned long *)buff = d << 10;
} else { /* MMC or SDC CSD v1.0 */ }
else { /* MMC or SDC CSD v1.0 */
b = (CardInfo[5] & 15) + ((CardInfo[10] & 128) >> 7) + ((CardInfo[9] & 3) << 1) + 2; b = (CardInfo[5] & 15) + ((CardInfo[10] & 128) >> 7) + ((CardInfo[9] & 3) << 1) + 2;
d = (CardInfo[8] >> 6) + ((unsigned short)CardInfo[7] << 2) + ((unsigned short)(CardInfo[6] & 3) << 10) + 1; d = (CardInfo[8] >> 6) + ((unsigned short)CardInfo[7] << 2) + ((unsigned short)(CardInfo[6] & 3) << 10) + 1;
*(unsigned long*)buff = d << (b - 9); *(unsigned long *)buff = d << (b - 9);
} }
res = RES_OK; res = RES_OK;
break; break;
case GET_SECTOR_SIZE : /* Get sectors on the disk (unsigned short) */ case GET_SECTOR_SIZE : /* Get sectors on the disk (unsigned short) */
*(unsigned short*)buff = 512; *(unsigned short *)buff = 512;
res = RES_OK; res = RES_OK;
break; break;
case GET_BLOCK_SIZE : /* Get erase block size in unit of sectors (unsigned long) */ case GET_BLOCK_SIZE : /* Get erase block size in unit of sectors (unsigned long) */
if (CardType & CT_SD2) { /* SDC ver 2.00 */ if(CardType & CT_SD2) { /* SDC ver 2.00 */
*(unsigned long*)buff = 16UL << (CardInfo[10] >> 4); *(unsigned long *)buff = 16UL << (CardInfo[10] >> 4);
} else { /* SDC ver 1.XX or MMC */
if (CardType & CT_SD1) /* SDC v1 */
*(unsigned long*)buff = (((CardInfo[10] & 63) << 1) + ((unsigned short)(CardInfo[11] & 128) >> 7) + 1) << ((CardInfo[13] >> 6) - 1);
else /* MMC */
*(unsigned long*)buff = ((unsigned short)((CardInfo[10] & 124) >> 2) + 1) * (((CardInfo[11] & 3) << 3) + ((CardInfo[11] & 224) >> 5) + 1);
} }
else { /* SDC ver 1.XX or MMC */
if(CardType & CT_SD1) { /* SDC v1 */
*(unsigned long *)buff = (((CardInfo[10] & 63) << 1) + ((unsigned short)(CardInfo[11] & 128) >> 7) + 1) << ((CardInfo[13] >> 6) - 1);
}
else { /* MMC */
*(unsigned long *)buff = ((unsigned short)((CardInfo[10] & 124) >> 2) + 1) * (((CardInfo[11] & 3) << 3) + ((CardInfo[11] & 224) >> 5) + 1);
}
}
res = RES_OK; res = RES_OK;
break; break;
case CTRL_ERASE_SECTOR : /* Erase a block of sectors */ case CTRL_ERASE_SECTOR : /* Erase a block of sectors */
if (!(CardType & CT_SDC) || (!(CardInfo[0] >> 6) && !(CardInfo[10] & 0x40))) break; /* Check if sector erase can be applied to the card */ if(!(CardType & CT_SDC) || (!(CardInfo[0] >> 6) && !(CardInfo[10] & 0x40))) {
dp = buff; st = dp[0]; ed = dp[1]; break; /* Check if sector erase can be applied to the card */
if (!(CardType & CT_BLOCK)) {
st *= 512; ed *= 512;
} }
if (send_cmd(CMD32, st, 1, resp) && send_cmd(CMD33, ed, 1, resp) && send_cmd(CMD38, 0, 1, resp) && wait_ready(30000))
dp = buff;
st = dp[0];
ed = dp[1];
if(!(CardType & CT_BLOCK)) {
st *= 512;
ed *= 512;
}
if(send_cmd(CMD32, st, 1, resp) && send_cmd(CMD33, ed, 1, resp) && send_cmd(CMD38, 0, 1, resp) && wait_ready(30000)) {
res = RES_OK; res = RES_OK;
}
break; break;
case CTRL_POWER : case CTRL_POWER :
switch (ptr[0]) { switch(ptr[0]) {
case 0: /* Sub control code == 0 (POWER_OFF) */ case 0: /* Sub control code == 0 (POWER_OFF) */
power_off(); /* Power off */ power_off(); /* Power off */
res = RES_OK; res = RES_OK;
break; break;
case 1: /* Sub control code == 1 (POWER_GET) */ case 1: /* Sub control code == 1 (POWER_GET) */
ptr[1] = (unsigned char)power_status(); ptr[1] = (unsigned char)power_status();
res = RES_OK; res = RES_OK;
break; break;
default : default :
res = RES_PARERR; res = RES_PARERR;
} }
break; break;
case MMC_GET_TYPE : /* Get card type flags (1 byte) */ case MMC_GET_TYPE : /* Get card type flags (1 byte) */
@ -865,20 +991,24 @@ DRESULT MCI_ioctl (
break; break;
case MMC_GET_SDSTAT : /* Receive SD status as a data block (64 bytes) */ case MMC_GET_SDSTAT : /* Receive SD status as a data block (64 bytes) */
if (CardType & CT_SDC) { /* SDC */ if(CardType & CT_SDC) { /* SDC */
if (wait_ready(500)) { if(wait_ready(500)) {
ready_reception(1, 64); /* Ready to receive data blocks */ ready_reception(1, 64); /* Ready to receive data blocks */
if (send_cmd(ACMD13, 0, 1, resp) /* Start to read */
if(send_cmd(ACMD13, 0, 1, resp) /* Start to read */
&& !(resp[0] & 0xC0580000)) { && !(resp[0] & 0xC0580000)) {
while ((XferWp == 0) && !(XferStat & 0xC)); while((XferWp == 0) && !(XferStat & 0xC));
if (!(XferStat & 0xC)) {
if(!(XferStat & 0xC)) {
Copy_al2un(buff, DmaBuff[0], 64); Copy_al2un(buff, DmaBuff[0], 64);
res = RES_OK; res = RES_OK;
} }
} }
} }
stop_transfer(); /* Close data path */ stop_transfer(); /* Close data path */
} }
break; break;
default: default:

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,10 +49,11 @@ 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;
@ -65,14 +66,15 @@ rtc_set_localtime(struct tm* localt)
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;
localt = localtime(&time); /* convert seconds to broken-down time */
rtc_set_localtime(localt); rtc_set_localtime(localt);
epoch = time - localt->tm_sec - localt->tm_min * 60; 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);
@ -80,9 +82,9 @@ void rtc_reset(void)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
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;
@ -91,18 +93,19 @@ rtc_set_alarm(struct tm* localt, enum rtc_alarm_mask mask)
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 { }
else {
RTC_AMR = 0xff; 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;
@ -111,39 +114,43 @@ rtc_get_alarm(struct tm* localt)
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) */
}
else if(RTC_ILR & ILR_RTCCIF) {
/* counter increase interrupt */
RTC_ILR |= ILR_RTCCIF; RTC_ILR |= ILR_RTCCIF;
epoch += 60 * 60; // add 1 hour epoch += 60 * 60; /* add 1 hour */
} else if( RTC_ILR & ILR_RTCALF ) { }
else if(RTC_ILR & ILR_RTCALF) {
RTC_ILR |= ILR_RTCALF; RTC_ILR |= ILR_RTCALF;
RTC_AMR = 0xff; // disable alarm irq RTC_AMR = 0xff; /* disable alarm irq */
DEBUG("Ring\n"); DEBUG("Ring\n");
lpm_end_awake(); lpm_end_awake();
} }
VICVectAddr = 0; // Acknowledge Interrupt 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);
@ -152,17 +159,17 @@ void rtc_enable(void)
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();
} }
@ -171,7 +178,7 @@ void rtc_init(void)
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;
@ -180,16 +187,17 @@ time_t rtc_time(struct timeval* time)
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) ) {
while(usec != (RTC_CTC >> 1)) {
usec = (RTC_CTC >> 1); usec = (RTC_CTC >> 1);
sec = RTC_SEC; sec = RTC_SEC;
min = RTC_MIN; min = RTC_MIN;
} }
sec += min * 60; // add number of minutes sec += min * 60; /* add number of minutes */
sec += epoch; // add precalculated epoch in hour granularity sec += epoch; /* add precalculated epoch in hour granularity */
if( time != NULL ) { if(time != NULL) {
usec = usec * 15625; usec = usec * 15625;
usec >>= 9; usec >>= 9;
time->tv_sec = sec; time->tv_sec = sec;
@ -201,15 +209,15 @@ time_t rtc_time(struct timeval* time)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
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;
@ -218,14 +226,15 @@ rtc_get_localtime(struct tm* localt)
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 ) {
if(ptimeval != NULL) {
rtc_time(ptimeval); 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,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. */ /* Enable interrupts. */
IE1 = ie1; IE1 = ie1;
IE2 = ie2; IE2 = ie2;
restoreIRQ(istate); 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"
@ -103,14 +103,14 @@ init_ports(void)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* 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! */
@ -133,10 +133,12 @@ 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 */ if(incr > (stack_pointer - cur_break)) {
return (void *) - 1; /* ENOMEM */
}
void *old_break = cur_break; void *old_break = cur_break;
cur_break += incr; cur_break += incr;
@ -155,8 +157,8 @@ 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. */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -167,7 +169,7 @@ 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. */ /* Enable interrupts. */
IE1 = ie1; IE1 = ie1;
IE2 = ie2; IE2 = ie2;
restoreIRQ(istate); 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

@ -17,15 +17,17 @@ void timerA_init(void)
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

@ -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,10 +185,12 @@ 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;
@ -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();