fixed coding conventions (mostly by astyle)
This commit is contained in:
parent
ffeb6f8523
commit
5d70656343
@ -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();
|
||||||
|
|||||||
@ -79,11 +79,13 @@ void thread_print_stack(void)
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,5 +96,6 @@ __attribute__((naked,noreturn)) void arm_reset(void)
|
|||||||
WDMOD = 0x03;
|
WDMOD = 0x03;
|
||||||
WDFEED = 0xAA;
|
WDFEED = 0xAA;
|
||||||
WDFEED = 0x55;
|
WDFEED = 0x55;
|
||||||
|
|
||||||
while(1);
|
while(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,23 +52,31 @@ 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) {};
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
@ -95,7 +103,8 @@ void abtorigin(const char* vector, u_long* lnk_ptr1)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
void UNDEF_Routine (void) {
|
void UNDEF_Routine(void)
|
||||||
|
{
|
||||||
register u_long *lnk_ptr;
|
register u_long *lnk_ptr;
|
||||||
__asm__ __volatile__("sub %0, lr, #8" : "=r"(lnk_ptr)); // get aborting instruction
|
__asm__ __volatile__("sub %0, lr, #8" : "=r"(lnk_ptr)); // get aborting instruction
|
||||||
|
|
||||||
@ -107,7 +116,8 @@ void UNDEF_Routine (void) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
void PABT_Routine (void) {
|
void PABT_Routine(void)
|
||||||
|
{
|
||||||
register u_long *lnk_ptr;
|
register u_long *lnk_ptr;
|
||||||
__asm__ __volatile__("sub %0, lr, #8" : "=r"(lnk_ptr)); // get aborting instruction
|
__asm__ __volatile__("sub %0, lr, #8" : "=r"(lnk_ptr)); // get aborting instruction
|
||||||
|
|
||||||
@ -119,7 +129,8 @@ void PABT_Routine (void) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
void DABT_Routine (void) {
|
void DABT_Routine(void)
|
||||||
|
{
|
||||||
register u_long *lnk_ptr;
|
register u_long *lnk_ptr;
|
||||||
__asm__ __volatile__("sub %0, lr, #8" : "=r"(lnk_ptr)); // get aborting instruction
|
__asm__ __volatile__("sub %0, lr, #8" : "=r"(lnk_ptr)); // get aborting instruction
|
||||||
|
|
||||||
@ -149,18 +160,23 @@ bl_init_data(void)
|
|||||||
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);
|
||||||
|
|||||||
@ -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,24 +20,28 @@
|
|||||||
|
|
||||||
#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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,59 +52,66 @@ static void timer_irq(void)
|
|||||||
*VULP(base + TXIR) = BIT0;
|
*VULP(base + TXIR) = BIT0;
|
||||||
int_handler(timer);
|
int_handler(timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*VULP(base + TXIR) & BIT1) {
|
if(*VULP(base + TXIR) & BIT1) {
|
||||||
*VULP(base + TXMCR) &= ~BIT3;
|
*VULP(base + TXMCR) &= ~BIT3;
|
||||||
*VULP(base + TXIR) = BIT1;
|
*VULP(base + TXIR) = BIT1;
|
||||||
int_handler(timer + 1);
|
int_handler(timer + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*VULP(base + TXIR) & BIT2) {
|
if(*VULP(base + TXIR) & BIT2) {
|
||||||
*VULP(base + TXMCR) &= ~BIT6;
|
*VULP(base + TXMCR) &= ~BIT6;
|
||||||
*VULP(base + TXIR) = BIT2;
|
*VULP(base + TXIR) = BIT2;
|
||||||
int_handler(timer + 2);
|
int_handler(timer + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*VULP(base + TXIR) & BIT3) {
|
if(*VULP(base + TXIR) & BIT3) {
|
||||||
*VULP(base + TXMCR) &= ~BIT9;
|
*VULP(base + TXMCR) &= ~BIT9;
|
||||||
*VULP(base + TXIR) = BIT3;
|
*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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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:
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -32,15 +31,14 @@ 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,7 +85,8 @@ 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;
|
||||||
|
|
||||||
@ -106,24 +100,30 @@ uint8_t flashrom_erase(uint8_t *addr) {
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,14 +23,17 @@ 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,21 +43,27 @@ 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++) {
|
for(i = 0; i < MAX_TRACED_FUNCTIONS; i++) {
|
||||||
if(functions[i].address == addr) {
|
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++;
|
||||||
@ -83,18 +92,23 @@ 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) {
|
||||||
@ -104,11 +118,14 @@ void __attribute__((__no_instrument_function__)) __cyg_profile_func_exit (void *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void profiling_stats(void) {
|
void profiling_stats(void)
|
||||||
|
{
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
|
|
||||||
for(i = 0; i < traced_functions; 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);
|
// 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("________________________________________________________");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
@ -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;
|
||||||
@ -127,6 +126,7 @@ caddr_t _sbrk_r(struct _reent *r, size_t 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
|
||||||
@ -139,6 +139,7 @@ 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
|
||||||
@ -151,11 +152,14 @@ 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)
|
||||||
{
|
{
|
||||||
@ -203,10 +207,12 @@ int _fstat_r(struct _reent *r, int fd, struct stat * st)
|
|||||||
|
|
||||||
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);
|
||||||
@ -218,6 +224,7 @@ int _fstat_r(struct _reent *r, int fd, struct stat * st)
|
|||||||
r->_errno = ENODEV;
|
r->_errno = ENODEV;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
@ -230,10 +237,13 @@ int _write_r(struct _reent *r, int fd, const void *data, unsigned int count)
|
|||||||
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 )
|
}
|
||||||
|
else if(hal_state == HAL_NOT_INITIALIZED) {
|
||||||
result = fw_puts((char *)data, count);
|
result = fw_puts((char *)data, count);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
result = fw_puts((char *)data, count);
|
result = fw_puts((char *)data, count);
|
||||||
#endif
|
#endif
|
||||||
@ -300,6 +310,7 @@ void _exit(int n)
|
|||||||
|
|
||||||
stdio_flush();
|
stdio_flush();
|
||||||
arm_reset();
|
arm_reset();
|
||||||
|
|
||||||
while(1);
|
while(1);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|||||||
@ -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));
|
while(!(RFDINIFG & RF1AIFCTL1));
|
||||||
|
|
||||||
i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status byte
|
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;
|
||||||
|
|||||||
@ -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,6 +76,7 @@ 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 */
|
||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -51,8 +51,10 @@ 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(i = 0; i < INT_PORTS; i++) {
|
||||||
for(j = 0; j < BITMASK_SIZE; j++) {
|
for(j = 0; j < BITMASK_SIZE; j++) {
|
||||||
cb[i][j] = NULL;
|
cb[i][j] = NULL;
|
||||||
@ -61,18 +63,21 @@ void gpioint_init(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
@ -96,6 +101,7 @@ bool gpioint_set(int port, uint32_t bitmask, int flags, fp_irqcb callback) {
|
|||||||
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;
|
||||||
@ -105,9 +111,11 @@ bool gpioint_set(int port, uint32_t bitmask, int flags, fp_irqcb callback) {
|
|||||||
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;
|
||||||
@ -130,16 +138,20 @@ bool gpioint_set(int port, uint32_t bitmask, int flags, fp_irqcb callback) {
|
|||||||
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,12 +166,15 @@ 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]();
|
||||||
}
|
}
|
||||||
@ -174,12 +189,14 @@ interrupt (PORT1_VECTOR) __attribute__ ((naked)) port1_isr(void) {
|
|||||||
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,13 +211,16 @@ 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]();
|
||||||
}
|
}
|
||||||
@ -217,9 +237,6 @@ interrupt (PORT2_VECTOR) __attribute__ ((naked)) port2_isr(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//else {
|
|
||||||
// cb[1][ifg_num]();
|
|
||||||
//}
|
|
||||||
|
|
||||||
P2IFG = 0x00;
|
P2IFG = 0x00;
|
||||||
P2IE = int_enable;
|
P2IE = int_enable;
|
||||||
|
|||||||
@ -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,7 +85,8 @@ 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;
|
||||||
@ -98,30 +101,38 @@ void rtc_get_localtime(struct tm* localt) {
|
|||||||
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,8 +180,10 @@ 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 */
|
||||||
@ -182,6 +201,7 @@ 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;
|
||||||
@ -191,5 +211,6 @@ interrupt(RTC_VECTOR) __attribute__ ((naked)) rtc_isr(void) {
|
|||||||
/* RTC alarm */
|
/* RTC alarm */
|
||||||
else if(RTCIV == RTC_RTCAIFG) {
|
else if(RTCIV == RTC_RTCAIFG) {
|
||||||
}
|
}
|
||||||
|
|
||||||
__exit_isr();
|
__exit_isr();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,8 @@ void timerA_init(void)
|
|||||||
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,7 +39,8 @@ 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;
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,12 +24,11 @@ bool cpu_install_irq( int IntNumber, void *HandlerAddr, int Priority )
|
|||||||
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);
|
||||||
|
|||||||
@ -27,23 +27,29 @@ void lpc2387_pclk_scale(uint32_t source, uint32_t target, uint32_t* pclksel, uin
|
|||||||
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);
|
||||||
@ -70,12 +76,11 @@ bool install_irq( int IntNumber, void *HandlerAddr, int Priority )
|
|||||||
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);
|
||||||
|
|||||||
@ -42,12 +42,13 @@ 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 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
@ -61,52 +62,56 @@ gpioint_set(int port, uint32_t bitmask, int flags, fp_irqcb callback)
|
|||||||
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)
|
||||||
@ -116,14 +121,15 @@ static void __attribute__ ((__no_instrument_function__)) test_irq(int port, unsi
|
|||||||
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 */
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -44,55 +44,67 @@ 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
|
if(lpm >= LPM_SLEEP) { // wake up from deep sleep
|
||||||
//benchmark
|
/* 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;
|
||||||
|
|
||||||
@ -105,7 +117,8 @@ enum lpm_mode lpm_set(enum lpm_mode target) {
|
|||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
enum lpm_mode
|
enum lpm_mode
|
||||||
lpm_get(void) {
|
lpm_get(void)
|
||||||
|
{
|
||||||
return lpm;
|
return lpm;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|||||||
@ -2,28 +2,36 @@
|
|||||||
#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;
|
||||||
}
|
}
|
||||||
@ -31,60 +39,79 @@ uint8_t iap_get_sector(uint32_t addr) {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -100,7 +100,8 @@ 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(ms & 0x400) { /* A block transfer completed (DataBlockEnd) */
|
||||||
if(xs & 1) { /* In card read operation */
|
if(xs & 1) { /* In card read operation */
|
||||||
if (ms & 0x100) /* When last block is received (DataEnd), */
|
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;
|
||||||
|
|
||||||
@ -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;
|
||||||
|
|
||||||
@ -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);
|
||||||
|
|
||||||
@ -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;
|
||||||
@ -361,25 +378,40 @@ 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;
|
||||||
@ -388,34 +420,39 @@ static int send_cmd (unsigned int idx, unsigned long arg, unsigned int rt, unsig
|
|||||||
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;
|
||||||
@ -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,12 +523,15 @@ 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();
|
||||||
|
|
||||||
@ -518,7 +561,8 @@ DSTATUS MCI_initialize (void) {
|
|||||||
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 */
|
||||||
}
|
}
|
||||||
@ -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 */
|
||||||
@ -553,7 +600,10 @@ DSTATUS MCI_initialize (void) {
|
|||||||
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 ----*/
|
||||||
|
|
||||||
@ -562,22 +612,28 @@ DSTATUS MCI_initialize (void) {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
@ -585,23 +641,24 @@ DSTATUS MCI_initialize (void) {
|
|||||||
/*---- 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(ty & CT_SDC) { /* Set wide bus mode (for SDCs) */
|
||||||
if(!send_cmd(ACMD6, 2, 1, resp) /* Set bus mode of SDC */
|
if(!send_cmd(ACMD6, 2, 1, resp) /* Set bus mode of SDC */
|
||||||
|| (resp[0] & 0xFDF90000))
|
|| (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 */
|
||||||
@ -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,27 +771,43 @@ 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(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 */
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,12 +818,15 @@ DRESULT MCI_write (const unsigned char *buff, unsigned long sector, unsigned cha
|
|||||||
|
|
||||||
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 */
|
||||||
|
|
||||||
@ -744,20 +834,33 @@ DRESULT MCI_write (const unsigned char *buff, unsigned long sector, unsigned cha
|
|||||||
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 */
|
|
||||||
|
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 */
|
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;
|
||||||
}
|
}
|
||||||
@ -780,25 +883,31 @@ 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;
|
||||||
|
|
||||||
@ -810,23 +919,37 @@ DRESULT MCI_ioctl (
|
|||||||
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 */
|
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);
|
*(unsigned long *)buff = (((CardInfo[10] & 63) << 1) + ((unsigned short)(CardInfo[11] & 128) >> 7) + 1) << ((CardInfo[13] >> 6) - 1);
|
||||||
else /* MMC */
|
}
|
||||||
|
else { /* MMC */
|
||||||
*(unsigned long *)buff = ((unsigned short)((CardInfo[10] & 124) >> 2) + 1) * (((CardInfo[11] & 3) << 3) + ((CardInfo[11] & 224) >> 5) + 1);
|
*(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 :
|
||||||
@ -835,13 +958,16 @@ DRESULT MCI_ioctl (
|
|||||||
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) */
|
||||||
@ -868,17 +994,21 @@ DRESULT MCI_ioctl (
|
|||||||
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:
|
||||||
|
|||||||
@ -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"
|
||||||
@ -51,8 +51,9 @@ static volatile time_t epoch;
|
|||||||
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;
|
struct tm *localt;
|
||||||
localt = localtime(&time); // convert seconds to broken-down time
|
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);
|
||||||
@ -91,10 +93,11 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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) {
|
if(RTC_ILR & ILR_RTSSF) {
|
||||||
// sub second interrupt (does not need flag-clearing)
|
/* sub second interrupt (does not need flag-clearing) */
|
||||||
|
|
||||||
} else if( RTC_ILR & ILR_RTCCIF ) {
|
}
|
||||||
// counter increase interrupt
|
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,13 +159,13 @@ 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. */
|
||||||
@ -180,14 +187,15 @@ 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;
|
||||||
@ -201,7 +209,7 @@ 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;
|
||||||
}
|
}
|
||||||
@ -218,13 +226,14 @@ 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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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();
|
||||||
|
|
||||||
@ -98,8 +58,6 @@ 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;
|
||||||
@ -109,9 +67,13 @@ char *thread_stack_init(void *task_func, void *stack_start, int stack_size)
|
|||||||
*stk = i;
|
*stk = i;
|
||||||
--stk;
|
--stk;
|
||||||
}
|
}
|
||||||
|
|
||||||
//stk -= 11;
|
//stk -= 11;
|
||||||
|
|
||||||
return (char *) stk;
|
return (char *) stk;
|
||||||
}
|
}
|
||||||
|
|
||||||
int inISR() { return __inISR; }
|
int inISR()
|
||||||
|
{
|
||||||
|
return __inISR;
|
||||||
|
}
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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");
|
||||||
@ -56,7 +57,8 @@ inline void __save_context_isr(void) {
|
|||||||
__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");
|
||||||
@ -73,35 +75,45 @@ 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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -6,23 +6,36 @@
|
|||||||
#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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -135,8 +135,10 @@ void *sbrk(int incr)
|
|||||||
|
|
||||||
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))
|
|
||||||
|
if(incr > (stack_pointer - cur_break)) {
|
||||||
return (void *) - 1; /* ENOMEM */
|
return (void *) - 1; /* ENOMEM */
|
||||||
|
}
|
||||||
|
|
||||||
void *old_break = cur_break;
|
void *old_break = cur_break;
|
||||||
cur_break += incr;
|
cur_break += incr;
|
||||||
|
|||||||
@ -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');
|
||||||
|
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -22,10 +22,12 @@ void timerA_init(void)
|
|||||||
*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,7 +36,8 @@ 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;
|
||||||
@ -43,7 +46,8 @@ interrupt(TIMERA1_VECTOR) __attribute__ ((naked)) timer_isr(void) {
|
|||||||
// 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);
|
||||||
|
|||||||
@ -27,6 +27,7 @@ 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:
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -84,12 +84,12 @@ unsigned long ts2ticks(struct timespec *tp)
|
|||||||
void schedule_timer(void)
|
void schedule_timer(void)
|
||||||
{
|
{
|
||||||
int l = next_timer;
|
int l = next_timer;
|
||||||
|
|
||||||
for(
|
for(
|
||||||
int i = ((next_timer + 1) % ARCH_MAXTIMERS);
|
int i = ((next_timer + 1) % ARCH_MAXTIMERS);
|
||||||
i != next_timer;
|
i != next_timer;
|
||||||
i = ((i + 1) % ARCH_MAXTIMERS)
|
i = ((i + 1) % ARCH_MAXTIMERS)
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
|
|
||||||
if(native_hwtimer_isset[l] != 1) {
|
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
|
||||||
@ -100,14 +100,15 @@ void schedule_timer(void)
|
|||||||
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) {
|
||||||
@ -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);
|
||||||
|
|||||||
@ -52,6 +52,7 @@ 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");
|
||||||
}
|
}
|
||||||
@ -63,6 +64,7 @@ void print_thread_sigmask(ucontext_t *cp)
|
|||||||
(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));
|
||||||
}
|
}
|
||||||
@ -89,12 +91,15 @@ 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");
|
||||||
}
|
}
|
||||||
@ -106,9 +111,11 @@ void native_print_signals()
|
|||||||
(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));
|
||||||
}
|
}
|
||||||
@ -129,20 +136,25 @@ unsigned disableIRQ(void)
|
|||||||
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;
|
||||||
@ -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;
|
||||||
@ -170,6 +183,7 @@ unsigned enableIRQ(void)
|
|||||||
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;
|
||||||
|
|
||||||
@ -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;
|
||||||
@ -199,6 +214,7 @@ void restoreIRQ(unsigned state)
|
|||||||
else {
|
else {
|
||||||
disableIRQ();
|
disableIRQ();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,10 +242,12 @@ 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,6 +264,7 @@ 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();
|
||||||
@ -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,6 +295,7 @@ 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.");
|
||||||
}
|
}
|
||||||
@ -283,6 +304,7 @@ void native_isr_entry(int sig, siginfo_t *info, void *context)
|
|||||||
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 */
|
||||||
|
|
||||||
@ -357,18 +379,22 @@ int unregister_interrupt(int sig)
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,9 +418,11 @@ void native_interrupt_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -421,6 +449,7 @@ void native_interrupt_init(void)
|
|||||||
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,9 +459,11 @@ 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;
|
||||||
|
|||||||
@ -47,6 +47,7 @@ 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 */
|
||||||
@ -56,6 +57,7 @@ void _native_lpm_sleep()
|
|||||||
/* 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();
|
||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -71,6 +71,7 @@ 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()");
|
||||||
}
|
}
|
||||||
@ -91,6 +92,7 @@ void cpu_switch_context_exit(void)
|
|||||||
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():");
|
||||||
}
|
}
|
||||||
@ -110,8 +112,10 @@ void thread_yield()
|
|||||||
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()");
|
||||||
}
|
}
|
||||||
@ -126,6 +130,7 @@ 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;
|
||||||
|
|||||||
@ -54,8 +54,10 @@ void rtc_set_localtime(struct tm* localt)
|
|||||||
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");
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user