diff --git a/bacnet-stack/ports/at91sam7s/init.c b/bacnet-stack/ports/at91sam7s/init.c index dd069486..28d70cef 100644 --- a/bacnet-stack/ports/at91sam7s/init.c +++ b/bacnet-stack/ports/at91sam7s/init.c @@ -32,71 +32,70 @@ extern void AT91F_Default_FIQ_handler(void); //*---------------------------------------------------------------------------- void LowLevelInit(void) { - int i; - AT91PS_PMC pPMC = AT91C_BASE_PMC; + int i; + AT91PS_PMC pPMC = AT91C_BASE_PMC; //* Set Flash Wait sate - // Single Cycle Access at Up to 30 MHz, or 40 - // if MCK = 48054841 I have 50 Cycle for 1 usecond ( flied MC_FMR->FMCN - // result: AT91C_MC_FMR = 0x00320100 (MC Flash Mode Register) - AT91C_BASE_MC->MC_FMR = (((AT91C_MC_FMCN) & (50 <<16)) | AT91C_MC_FWS_1FWS); + // Single Cycle Access at Up to 30 MHz, or 40 + // if MCK = 48054841 I have 50 Cycle for 1 usecond ( flied MC_FMR->FMCN + // result: AT91C_MC_FMR = 0x00320100 (MC Flash Mode Register) + AT91C_BASE_MC->MC_FMR = (((AT91C_MC_FMCN) & (50 <<16)) | AT91C_MC_FWS_1FWS); //* Watchdog Disable // result: AT91C_WDTC_WDMR = 0x00008000 (Watchdog Mode Register) - AT91C_BASE_WDTC->WDTC_WDMR= AT91C_WDTC_WDDIS; + AT91C_BASE_WDTC->WDTC_WDMR= AT91C_WDTC_WDDIS; - //* Set MCK at 48 054 841 + //* Set MCK at 48 054 841 // 1 Enabling the Main Oscillator: - // SCK = 1/32768 = 30.51 uSecond - // Start up time = 8 * 6 / SCK = 56 * 30.51 = 1,46484375 ms - // result: AT91C_CKGR_MOR = 0x00000601 (Main Oscillator Register) - pPMC->PMC_MOR = ((AT91C_CKGR_OSCOUNT & (0x06<<8)) | AT91C_CKGR_MOSCEN); - - // Wait the startup time - while(!(pPMC->PMC_SR & AT91C_PMC_MOSCS)); - - // PMC Clock Generator PLL Register setup - // - // The following settings are used: DIV = 14 - // MUL = 72 - // PLLCOUNT = 10 - // - // Main Clock (MAINCK from crystal oscillator) = 18432000 hz (see AT91SAM7-EK schematic) - // MAINCK / DIV = 18432000/14 = 1316571 hz - // PLLCK = 1316571 * (MUL + 1) = 1316571 * (72 + 1) = 1316571 * 73 = 96109683 hz - // - // PLLCOUNT = number of slow clock cycles before the LOCK bit is set - // in PMC_SR after CKGR_PLLR is written. - // - // PLLCOUNT = 10 - // - // OUT = 0 (not used) - // result: AT91C_CKGR_PLLR = 0x00000000480A0E (PLL Register) - pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 14) | + // SCK = 1/32768 = 30.51 uSecond + // Start up time = 8 * 6 / SCK = 56 * 30.51 = 1,46484375 ms + // result: AT91C_CKGR_MOR = 0x00000601 (Main Oscillator Register) + pPMC->PMC_MOR = ((AT91C_CKGR_OSCOUNT & (0x06<<8)) | AT91C_CKGR_MOSCEN); + + // Wait the startup time + while(!(pPMC->PMC_SR & AT91C_PMC_MOSCS)); + + // PMC Clock Generator PLL Register setup + // + // The following settings are used: DIV = 14 + // MUL = 72 + // PLLCOUNT = 10 + // + // Main Clock (MAINCK from crystal oscillator) = 18432000 hz (see AT91SAM7-EK schematic) + // MAINCK / DIV = 18432000/14 = 1316571 hz + // PLLCK = 1316571 * (MUL + 1) = 1316571 * (72 + 1) = 1316571 * 73 = 96109683 hz + // + // PLLCOUNT = number of slow clock cycles before the LOCK bit is set + // in PMC_SR after CKGR_PLLR is written. + // + // PLLCOUNT = 10 + // + // OUT = 0 (not used) + // result: AT91C_CKGR_PLLR = 0x00000000480A0E (PLL Register) + pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 14) | (AT91C_CKGR_PLLCOUNT & (10<<8)) | (AT91C_CKGR_MUL & (72<<16))); - // Wait the startup time (until PMC Status register LOCK bit is set) - while(!(pPMC->PMC_SR & AT91C_PMC_LOCK)); - - // PMC Master Clock (MCK) Register setup - // - // CSS = 3 (PLLCK clock selected) - // - // PRES = 1 (MCK = PLLCK / 2) = 96109683/2 = 48054841 hz - // - // Note: Master Clock MCK = 48054841 hz (this is the CPU clock speed) - // result: AT91C_PMC_MCKR = 0x00000007 (Master Clock Register) - pPMC->PMC_MCKR = AT91C_PMC_CSS_PLL_CLK | AT91C_PMC_PRES_CLK_2; - - // Set up the default interrupts handler vectors - AT91C_BASE_AIC->AIC_SVR[0] = (int) AT91F_Default_FIQ_handler; - for (i = 1; i < 31; i++) - { - AT91C_BASE_AIC->AIC_SVR[i] = (int) AT91F_Default_IRQ_handler; - } - AT91C_BASE_AIC->AIC_SPU = (int) AT91F_Spurious_handler; - + // Wait the startup time (until PMC Status register LOCK bit is set) + while(!(pPMC->PMC_SR & AT91C_PMC_LOCK)); + + // PMC Master Clock (MCK) Register setup + // + // CSS = 3 (PLLCK clock selected) + // + // PRES = 1 (MCK = PLLCK / 2) = 96109683/2 = 48054841 hz + // + // Note: Master Clock MCK = 48054841 hz (this is the CPU clock speed) + // result: AT91C_PMC_MCKR = 0x00000007 (Master Clock Register) + pPMC->PMC_MCKR = AT91C_PMC_CSS_PLL_CLK | AT91C_PMC_PRES_CLK_2; + + // Set up the default interrupts handler vectors + AT91C_BASE_AIC->AIC_SVR[0] = (int) AT91F_Default_FIQ_handler; + for (i = 1; i < 31; i++) + { + AT91C_BASE_AIC->AIC_SVR[i] = (int) AT91F_Default_IRQ_handler; + } + AT91C_BASE_AIC->AIC_SPU = (int) AT91F_Spurious_handler; } diff --git a/bacnet-stack/ports/at91sam7s/isr.c b/bacnet-stack/ports/at91sam7s/isr.c index fca4dc8b..b65041b3 100644 --- a/bacnet-stack/ports/at91sam7s/isr.c +++ b/bacnet-stack/ports/at91sam7s/isr.c @@ -23,65 +23,65 @@ static inline unsigned __get_cpsr(void) { - unsigned long retval; - asm volatile (" mrs %0, cpsr" : "=r" (retval) : /* no inputs */ ); - return retval; + unsigned long retval; + asm volatile (" mrs %0, cpsr" : "=r" (retval) : /* no inputs */ ); + return retval; } static inline void __set_cpsr(unsigned val) { - asm volatile (" msr cpsr, %0" : /* no outputs */ : "r" (val) ); + asm volatile (" msr cpsr, %0" : /* no outputs */ : "r" (val) ); } unsigned disableIRQ(void) { - unsigned _cpsr; - _cpsr = __get_cpsr(); - __set_cpsr(_cpsr | IRQ_MASK); - return _cpsr; + unsigned _cpsr; + _cpsr = __get_cpsr(); + __set_cpsr(_cpsr | IRQ_MASK); + return _cpsr; } unsigned restoreIRQ(unsigned oldCPSR) { - unsigned _cpsr; + unsigned _cpsr; - _cpsr = __get_cpsr(); - __set_cpsr((_cpsr & ~IRQ_MASK) | (oldCPSR & IRQ_MASK)); - return _cpsr; + _cpsr = __get_cpsr(); + __set_cpsr((_cpsr & ~IRQ_MASK) | (oldCPSR & IRQ_MASK)); + return _cpsr; } unsigned enableIRQ(void) { - unsigned _cpsr; + unsigned _cpsr; - _cpsr = __get_cpsr(); - __set_cpsr(_cpsr & ~IRQ_MASK); - return _cpsr; + _cpsr = __get_cpsr(); + __set_cpsr(_cpsr & ~IRQ_MASK); + return _cpsr; } unsigned disableFIQ(void) { - unsigned _cpsr; + unsigned _cpsr; - _cpsr = __get_cpsr(); - __set_cpsr(_cpsr | FIQ_MASK); - return _cpsr; + _cpsr = __get_cpsr(); + __set_cpsr(_cpsr | FIQ_MASK); + return _cpsr; } unsigned restoreFIQ(unsigned oldCPSR) { - unsigned _cpsr; + unsigned _cpsr; - _cpsr = __get_cpsr(); - __set_cpsr((_cpsr & ~FIQ_MASK) | (oldCPSR & FIQ_MASK)); - return _cpsr; + _cpsr = __get_cpsr(); + __set_cpsr((_cpsr & ~FIQ_MASK) | (oldCPSR & FIQ_MASK)); + return _cpsr; } unsigned enableFIQ(void) { - unsigned _cpsr; + unsigned _cpsr; - _cpsr = __get_cpsr(); - __set_cpsr(_cpsr & ~FIQ_MASK); - return _cpsr; + _cpsr = __get_cpsr(); + __set_cpsr(_cpsr & ~FIQ_MASK); + return _cpsr; } diff --git a/bacnet-stack/ports/at91sam7s/main.c b/bacnet-stack/ports/at91sam7s/main.c index cbcec1fc..d7edfaf6 100644 --- a/bacnet-stack/ports/at91sam7s/main.c +++ b/bacnet-stack/ports/at91sam7s/main.c @@ -1,6 +1,7 @@ /************************************************************************** * * Copyright (C) 2007 Steve Karg +* Portions of the AT91SAM7S startup code were developed by James P Lynch. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -38,17 +39,17 @@ #include "handlers.h" // ******************************************************* -// FIXME: put in header files External References +// FIXME: use header files? External References // ******************************************************* -extern void LowLevelInit(void); -extern unsigned enableIRQ(void); -extern unsigned enableFIQ(void); +extern void LowLevelInit(void); +extern unsigned enableIRQ(void); +extern unsigned enableFIQ(void); -extern void TimerInit(void); +extern void TimerInit(void); extern volatile unsigned long Timer_Milliseconds; // ******************************************************* -// Global Variables - ??? +// FIXME: use header files? Global Variables // ******************************************************* unsigned int FiqCount = 0; @@ -78,38 +79,55 @@ void millisecond_timer(void) } } -int main (void) { - unsigned long IdleCount = 0; // idle loop blink counter (2x) +int main (void) { + unsigned long IdleCount = 0; // idle loop blink counter bool LED3_Off_Enabled = true; uint16_t pdu_len = 0; BACNET_ADDRESS src; /* source address */ uint8_t pdu[MAX_MPDU]; /* PDU data */ - - // Initialize the Atmel AT91SAM7S256 (watchdog, PLL clock, default interrupts, etc.) + + // Initialize the Atmel AT91SAM7S256 + // (watchdog, PLL clock, default interrupts, etc.) LowLevelInit(); TimerInit(); /* Initialize the Parallel I/O Controller A Peripheral Clock */ - volatile AT91PS_PMC pPMC = AT91C_BASE_PMC; + volatile AT91PS_PMC pPMC = AT91C_BASE_PMC; pPMC->PMC_PCER = pPMC->PMC_PCSR | (1<PIO_PER = LED_MASK | SW1_MASK; // PIO Enable Register - allow PIO to control pins P0 - P3 and pin 19 - pPIO->PIO_OER = LED_MASK; // PIO Output Enable Register - sets pins P0 - P3 to outputs - pPIO->PIO_SODR = LED_MASK; // PIO Set Output Data Register - turns off the four LEDs - + volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; + // PIO Enable Register + // allow PIO to control pins P0 - P3 and pin 19 + pPIO->PIO_PER = LED_MASK | SW1_MASK; + // PIO Output Enable Register + // sets pins P0 - P3 to outputs + pPIO->PIO_OER = LED_MASK; + // PIO Set Output Data Register + // turns off the four LEDs + pPIO->PIO_SODR = LED_MASK; + // Select PA19 (pushbutton) to be FIQ function (Peripheral B) pPIO->PIO_BSR = SW1_MASK; - + // Set up the AIC registers for FIQ (pushbutton SW1) - volatile AT91PS_AIC pAIC = AT91C_BASE_AIC; // pointer to AIC data structure - pAIC->AIC_IDCR = (1<AIC_SMR[AT91C_ID_FIQ] = // Set the interrupt source type in AIC Source - (AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED); // Mode Register[0] - pAIC->AIC_ICCR = (1<AIC_IDCR = (0<AIC_IECR = (1<AIC_IDCR = (1<AIC_SMR[AT91C_ID_FIQ] = + (AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED); + // Clear the FIQ interrupt in + // AIC Interrupt Clear Command Register + pAIC->AIC_ICCR = (1<AIC_IDCR = (0<AIC_IECR = (1<PIO_SODR = LED3; LED3_Off_Enabled = true; } if (!LED_Timer_4) { - if ((pPIO->PIO_ODSR & LED4) == LED4) - pPIO->PIO_CODR = LED4; // turn LED2 (DS2) on - else - pPIO->PIO_SODR = LED4; // turn LED2 (DS2) off + if ((pPIO->PIO_ODSR & LED4) == LED4) { + // turn LED2 (DS2) on + pPIO->PIO_CODR = LED4; + } else { + // turn LED2 (DS2) off + pPIO->PIO_SODR = LED4; + } /* wait */ LED_Timer_4 = 1000; } - - IdleCount++; // count # of times through the idle loop - + // count # of times through the idle loop + IdleCount++; /* BACnet handling */ pdu_len = datalink_receive(&src, &pdu[0], MAX_MPDU, 0); if (pdu_len) { @@ -176,8 +196,3 @@ int main (void) { } } } - - - - - diff --git a/bacnet-stack/ports/at91sam7s/rs485.c b/bacnet-stack/ports/at91sam7s/rs485.c index d0aceea1..aa386165 100644 --- a/bacnet-stack/ports/at91sam7s/rs485.c +++ b/bacnet-stack/ports/at91sam7s/rs485.c @@ -1,6 +1,7 @@ /************************************************************************** * * Copyright (C) 2007 Steve Karg +* RS-485 initialization on AT91SAM7S inspired by Keil Eletronik serial.c * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the diff --git a/bacnet-stack/ports/at91sam7s/timer.c b/bacnet-stack/ports/at91sam7s/timer.c index 2ca19c75..012f2384 100644 --- a/bacnet-stack/ports/at91sam7s/timer.c +++ b/bacnet-stack/ports/at91sam7s/timer.c @@ -21,7 +21,7 @@ // count = 46.928 // // -// Therefore: set Timer Channel 0 register RC to 9835 +// Therefore: set Timer Channel 0 register RC to 46*milliseconds // turn on capture mode WAVE = 0 // enable the clock CLKEN = 1 // select TIMER_CLOCK5 TCCLKS = 100 @@ -57,8 +57,10 @@ void Timer0_Setup(int milliseconds) { // SYNC = 0 (no effect) <===== take default // SYNC = 1 (generate software trigger for all 3 timer channels simultaneously) // - AT91PS_TCB pTCB = AT91C_BASE_TCB; // create a pointer to TC Global Register structure - pTCB->TCB_BCR = 0; // SYNC trigger not used + // create a pointer to TC Global Register structure + AT91PS_TCB pTCB = AT91C_BASE_TCB; + // SYNC trigger not used + pTCB->TCB_BCR = 0; // TC Block Mode Register TC_BMR (read/write) // @@ -82,7 +84,8 @@ void Timer0_Setup(int milliseconds) { // = 10 TIOA0 (PA00) // = 11 TIOA1 (PA26) // - pTCB->TCB_BMR = 0x15; // external clocks not used + // external clocks not used + pTCB->TCB_BMR = 0x15; // TC Channel Control Register TC_CCR (read/write) @@ -101,8 +104,10 @@ void Timer0_Setup(int milliseconds) { // SWTRG = 0 no effect // SWTRG = 1 software trigger aserted counter reset and clock starts <===== we select this one // - AT91PS_TC pTC = AT91C_BASE_TC0; // create a pointer to channel 0 Register structure - pTC->TC_CCR = 0x5; // enable the clock and start it + // create a pointer to channel 0 Register structure + AT91PS_TC pTC = AT91C_BASE_TC0; + // enable the clock and start it + pTC->TC_CCR = 0x5; // TC Channel Mode Register TC_CMR (read/write) // @@ -179,9 +184,10 @@ void Timer0_Setup(int milliseconds) { // 10 (falling edge of TIOA) // 11 (each edge of TIOA) // - pTC->TC_CMR = 0x4004; // TCCLKS = 1 (TIMER_CLOCK5) - // CPCTRG = 1 (RC Compare resets the counter and restarts the clock) - // WAVE = 0 (Capture mode enabled) + // TCCLKS = 1 (TIMER_CLOCK5) + // CPCTRG = 1 (RC Compare resets the counter and restarts the clock) + // WAVE = 0 (Capture mode enabled) + pTC->TC_CMR = 0x4004; // TC Register C TC_RC (read/write) Compare Register 16-bits // @@ -238,7 +244,8 @@ void Timer0_Setup(int milliseconds) { // ETRGS = 0 no effect <===== take default // 1 enable External Trigger interrupt // - pTC->TC_IER = 0x10; // enable RC compare interrupt + // enable RC compare interrupt + pTC->TC_IER = 0x10; // TC Interrupt Disable Register TC_IDR (write-only) // @@ -272,7 +279,8 @@ void Timer0_Setup(int milliseconds) { // ETRGS = 0 no effect // 1 disable External Trigger interrupt <===== we select this one // - pTC->TC_IDR = 0xEF; // disable all except RC compare interrupt + // disable all except RC compare interrupt + pTC->TC_IDR = 0xEF; } // ***************************************************************************** @@ -296,6 +304,15 @@ void Timer0IrqHandler (void) { Timer_Milliseconds++; } +// ***************************************************************************** +// +// Timer 0 Initialization +// +// From James P Lynch main.c example code +// Modified by Steve Karg +// Moved timer startup code from main +// modified the peripheral clock init +// ***************************************************************************** void TimerInit(void) { // enable the Timer0 peripheral clock volatile AT91PS_PMC pPMC = AT91C_BASE_PMC; @@ -313,13 +330,13 @@ void TimerInit(void) { // in AIC Source Mode Register[12] pAIC->AIC_SMR[AT91C_ID_TC0] = (AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE | 0x4 ); - // Clear the TC0 interrupt + // Clear the TC0 interrupt // in AIC Interrupt Clear Command Register pAIC->AIC_ICCR = (1<AIC_IDCR = (0<AIC_IECR = (1<