From f1deb0b1fe375909cda34568f3d5318c996d5086 Mon Sep 17 00:00:00 2001 From: skarg Date: Thu, 9 Aug 2007 23:53:18 +0000 Subject: [PATCH] Tweaked the Atmel ARM7 MS/TP settings. --- bacnet-stack/mstp.c | 4 +- bacnet-stack/mstp.h | 4 +- bacnet-stack/ports/at91sam7s/dlmstp.c | 12 +- bacnet-stack/ports/at91sam7s/makefile | 3 +- bacnet-stack/ports/at91sam7s/rs485.c | 43 ++- bacnet-stack/ports/at91sam7s/timer.c | 521 +++++++++++++------------- 6 files changed, 301 insertions(+), 286 deletions(-) diff --git a/bacnet-stack/mstp.c b/bacnet-stack/mstp.c index 25ea0693..fb14bf01 100644 --- a/bacnet-stack/mstp.c +++ b/bacnet-stack/mstp.c @@ -917,7 +917,7 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port) /* The PASS_TOKEN state listens for a successor to begin using */ /* the token that this node has just attempted to pass. */ case MSTP_MASTER_STATE_PASS_TOKEN: - if (mstp_port->SilenceTimer < Tusage_timeout) { + if (mstp_port->SilenceTimer <= Tusage_timeout) { if (mstp_port->EventCount > Nmin_octets) { /* SawTokenUser */ /* Assume that a frame has been sent by the new token user. */ @@ -1026,7 +1026,7 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port) transition_now = true; } mstp_port->ReceivedValidFrame = false; - } else if ((mstp_port->SilenceTimer >= Tusage_timeout) || + } else if ((mstp_port->SilenceTimer > Tusage_timeout) || (mstp_port->ReceivedInvalidFrame == true)) { if (mstp_port->SoleMaster == true) { /* SoleMaster */ diff --git a/bacnet-stack/mstp.h b/bacnet-stack/mstp.h index 191af97a..df95c34e 100644 --- a/bacnet-stack/mstp.h +++ b/bacnet-stack/mstp.h @@ -99,13 +99,13 @@ typedef enum { /* that a node must wait for a station to begin replying to a */ /* confirmed request: 255 milliseconds. (Implementations may use */ /* larger values for this timeout, not to exceed 300 milliseconds.) */ -#define Treply_timeout 255 +#define Treply_timeout 260 /* The minimum time without a DataAvailable or ReceiveError event that a */ /* node must wait for a remote node to begin using a token or replying to */ /* a Poll For Master frame: 20 milliseconds. (Implementations may use */ /* larger values for this timeout, not to exceed 100 milliseconds.) */ -#define Tusage_timeout 20 +#define Tusage_timeout 25 struct mstp_port_struct_t { diff --git a/bacnet-stack/ports/at91sam7s/dlmstp.c b/bacnet-stack/ports/at91sam7s/dlmstp.c index 3f92eb78..20a0f807 100644 --- a/bacnet-stack/ports/at91sam7s/dlmstp.c +++ b/bacnet-stack/ports/at91sam7s/dlmstp.c @@ -124,9 +124,12 @@ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */ static void dlmstp_task(void) { + volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; /* only do receive state machine while we don't have a frame */ if ((MSTP_Port.ReceivedValidFrame == false) && (MSTP_Port.ReceivedInvalidFrame == false)) { + /* LED OFF */ + pPIO->PIO_SODR = LED2; do { RS485_Check_UART_Data(&MSTP_Port); MSTP_Receive_Frame_FSM(&MSTP_Port); @@ -135,13 +138,8 @@ static void dlmstp_task(void) break; } while (MSTP_Port.DataAvailable); } else { - /* toggle LED on Frame received */ - volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; - if ((pPIO->PIO_ODSR & LED2) == LED2) - pPIO->PIO_CODR = LED2; - else - pPIO->PIO_SODR = LED2; - + /* LED ON */ + pPIO->PIO_CODR = LED2; } /* only do master state machine while rx is idle */ if (MSTP_Port.receive_state == MSTP_RECEIVE_STATE_IDLE) { diff --git a/bacnet-stack/ports/at91sam7s/makefile b/bacnet-stack/ports/at91sam7s/makefile index 548f7cbe..354b5e58 100644 --- a/bacnet-stack/ports/at91sam7s/makefile +++ b/bacnet-stack/ports/at91sam7s/makefile @@ -12,7 +12,8 @@ LDSCRIPT=at91sam7s256.ld BACNET_FLAGS = -DBACDL_MSTP=1 -DPRINT_ENABLED=0 -DBIG_ENDIAN=0 -DMAX_APDU=480 -DDLMSTP_TEST INCLUDES = -I. -I../.. -I../../demo/handler -I../../demo/object -OPTIMIZATION = -O0 +#OPTIMIZATION = -O0 +OPTIMIZATION = -Os CFLAGS = -fno-common $(OPTIMIZATION) $(INCLUDES) $(BACNET_FLAGS) -Wall -g # -Wa, Pass comma-separated on to the assembler AFLAGS = -Wa,-ahls,-mapcs-32,-adhlns=$(<:.s=.lst) diff --git a/bacnet-stack/ports/at91sam7s/rs485.c b/bacnet-stack/ports/at91sam7s/rs485.c index 3ed660f6..d0aceea1 100644 --- a/bacnet-stack/ports/at91sam7s/rs485.c +++ b/bacnet-stack/ports/at91sam7s/rs485.c @@ -33,12 +33,12 @@ #include #include "mstp.h" -/* This file has been customized for use with UART0 +/* This file has been customized for use with UART0 on the AT91SAM7S-EK */ #include "board.h" /* UART */ -static AT91S_USART *RS485_Interface = AT91C_BASE_US0; +static volatile AT91S_USART *RS485_Interface = AT91C_BASE_US0; /* baud rate */ static int RS485_Baud = 38400; @@ -50,7 +50,7 @@ static int RS485_Baud = 38400; *****************************************************************************/ void RS485_Set_Interface(char *ifname) { - RS485_Interface = (AT91S_USART *)ifname; + RS485_Interface = (volatile AT91S_USART *)ifname; } /**************************************************************************** @@ -63,32 +63,32 @@ void RS485_Set_Interface(char *ifname) void RS485_Initialize(void) { // enable the USART0 peripheral clock - volatile AT91PS_PMC pPMC = AT91C_BASE_PMC; + volatile AT91PS_PMC pPMC = AT91C_BASE_PMC; pPMC->PMC_PCER = pPMC->PMC_PCSR | (1<US_CR = + RS485_Interface->US_CR = AT91C_US_RSTRX | /* Reset Receiver */ AT91C_US_RSTTX | /* Reset Transmitter */ AT91C_US_RXDIS | /* Receiver Disable */ AT91C_US_TXDIS; /* Transmitter Disable */ - RS485_Interface->US_MR = - AT91C_US_USMODE_RS485 | /* RS-485 Mode - RTS auto asserted */ + RS485_Interface->US_MR = + AT91C_US_USMODE_RS485 | /* RS-485 Mode - RTS auto assert */ AT91C_US_CLKS_CLOCK | /* Clock = MCK */ AT91C_US_CHRL_8_BITS | /* 8-bit Data */ AT91C_US_PAR_NONE | /* No Parity */ AT91C_US_NBSTOP_1_BIT; /* 1 Stop Bit */ - + /* set the Time Guard to release RTS after x bit times */ RS485_Interface->US_TTGR = 4; /* baud rate */ RS485_Interface->US_BRGR = MCK/16/RS485_Baud; - RS485_Interface->US_CR = + RS485_Interface->US_CR = AT91C_US_RXEN | /* Receiver Enable */ AT91C_US_TXEN; /* Transmitter Enable */ @@ -146,32 +146,26 @@ void RS485_Send_Frame( uint16_t nbytes) /* number of bytes of data (up to 501) */ { uint8_t turnaround_time; - uint32_t baud; /* toggle LED on send */ volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; - if ((pPIO->PIO_ODSR & LED1) == LED1) - pPIO->PIO_CODR = LED1; - else - pPIO->PIO_SODR = LED1; + /* LED ON */ + pPIO->PIO_CODR = LED1; /* delay after reception - per MS/TP spec */ if (mstp_port) { - baud = RS485_Get_Baud_Rate(); /* wait about 40 bit times since reception */ - if (baud == 9600) - turnaround_time = 4; - else if (baud == 19200) - turnaround_time = 2; - else + turnaround_time = (40*1000)/RS485_Baud; + if (!turnaround_time) { turnaround_time = 1; + } while (mstp_port->SilenceTimer < turnaround_time) { /* do nothing - wait for timer to increment */ }; } while (nbytes) { while (!(RS485_Interface->US_CSR & AT91C_US_TXRDY)) { - /* do nothing - wait for Tx buffer to get empty */ - } + /* do nothing - wait until Tx buffer is empty */ + } RS485_Interface->US_THR = *buffer; buffer++; nbytes--; @@ -180,6 +174,11 @@ void RS485_Send_Frame( mstp_port->SilenceTimer = 0; } } + while (!(RS485_Interface->US_CSR & AT91C_US_TXRDY)) { + /* do nothing - wait until Tx buffer is empty */ + } + /* LED OFF */ + pPIO->PIO_SODR = LED1; return; } diff --git a/bacnet-stack/ports/at91sam7s/timer.c b/bacnet-stack/ports/at91sam7s/timer.c index a65a5d08..2ca19c75 100644 --- a/bacnet-stack/ports/at91sam7s/timer.c +++ b/bacnet-stack/ports/at91sam7s/timer.c @@ -2,23 +2,23 @@ // // Purpose: Set up the 16-bit Timer/Counter // -// We will use Timer Channel 0 to develop a 50 msec interrupt. +// We will use Timer Channel 0 to develop a 1 msec interrupt. // // The AT91SAM7S-EK board has a 18,432,000 hz crystal oscillator. // // MAINCK = 18432000 hz -// PLLCK = (MAINCK / DIV) * (MUL + 1) = 18432000/14 * (72 + 1) +// PLLCK = (MAINCK / DIV) * (MUL + 1) = 18432000/14 * (72 + 1) // PLLCLK = 1316571 * 73 = 96109683 hz // -// MCK = PLLCLK / 2 = 96109683 / 2 = 48054841 hz +// MCK = PLLCLK / 2 = 96109683 / 2 = 48054841 hz // // TIMER_CLOCK5 = MCK / 1024 = 48054841 / 1024 = 46928 hz // // TIMER_CLOCK5 Period = 1 / 46928 = 21.309239686 microseconds // -// A little algebra: .050 sec = count * 21.3092396896*10**-6 -// count = .050 / 21.3092396896*10**-6 -// count = 2346 +// A little algebra: .001 sec = count * 21.3092396896*10**-6 +// count = .001 / 21.3092396896*10**-6 +// count = 46.928 // // // Therefore: set Timer Channel 0 register RC to 9835 @@ -31,280 +31,297 @@ // disable all the other timer 0 interrupts // // Author: James P Lynch May 12, 2007 +// Modified by Steve Karg +// Changed timer to 1ms. +// Encapsulated the intialization // ***************************************************************************** /********************************************************** - Header files + Header files **********************************************************/ #include "AT91SAM7S256.h" #include "board.h" // global variable counts interrupts -volatile unsigned long Timer_Milliseconds = 0; +volatile unsigned long Timer_Milliseconds = 0; -void TimerSetup(void) { - - // TC Block Control Register TC_BCR (read/write) - // - // |------------------------------------------------------------------|------| - // | SYNC | - // |------------------------------------------------------------------|------| - // 31 1 0 - // - // 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 - - // TC Block Mode Register TC_BMR (read/write) - // - // |-------------------------------------|-----------|-----------|-----------| - // | TC2XC2S TCXC1S TC0XC0S | - // |-------------------------------------|-----------|-----------|-----------| - // 31 5 4 3 2 1 0 - // - // TC0XC0S Select = 00 TCLK0 (PA4) - // = 01 none <===== we select this one - // = 10 TIOA1 (PA15) - // = 11 TIOA2 (PA26) - // - // TCXC1S Select = 00 TCLK1 (PA28) - // = 01 none <===== we select this one - // = 10 TIOA0 (PA15) - // = 11 TIOA2 (PA26) - // - // TC2XC2S Select = 00 TCLK2 (PA29) - // = 01 none <===== we select this one - // = 10 TIOA0 (PA00) - // = 11 TIOA1 (PA26) - // - pTCB->TCB_BMR = 0x15; // external clocks not used +void Timer0_Setup(int milliseconds) { + // TC Block Control Register TC_BCR (read/write) + // + // |------------------------------------------------------------------|------| + // | SYNC | + // |------------------------------------------------------------------|------| + // 31 1 0 + // + // 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 + + // TC Block Mode Register TC_BMR (read/write) + // + // |-------------------------------------|-----------|-----------|-----------| + // | TC2XC2S TCXC1S TC0XC0S | + // |-------------------------------------|-----------|-----------|-----------| + // 31 5 4 3 2 1 0 + // + // TC0XC0S Select = 00 TCLK0 (PA4) + // = 01 none <===== we select this one + // = 10 TIOA1 (PA15) + // = 11 TIOA2 (PA26) + // + // TCXC1S Select = 00 TCLK1 (PA28) + // = 01 none <===== we select this one + // = 10 TIOA0 (PA15) + // = 11 TIOA2 (PA26) + // + // TC2XC2S Select = 00 TCLK2 (PA29) + // = 01 none <===== we select this one + // = 10 TIOA0 (PA00) + // = 11 TIOA1 (PA26) + // + pTCB->TCB_BMR = 0x15; // external clocks not used - // TC Channel Control Register TC_CCR (read/write) - // - // |----------------------------------|--------------|------------|-----------| - // | SWTRG CLKDIS CLKENS | - // |----------------------------------|--------------|------------|-----------| - // 31 2 1 0 - // - // CLKEN = 0 no effect - // CLKEN = 1 enables the clock <===== we select this one - // - // CLKDIS = 0 no effect <===== take default - // CLKDIS = 1 disables the clock - // - // 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 + // TC Channel Control Register TC_CCR (read/write) + // + // |----------------------------------|--------------|------------|-----------| + // | SWTRG CLKDIS CLKENS | + // |----------------------------------|--------------|------------|-----------| + // 31 2 1 0 + // + // CLKEN = 0 no effect + // CLKEN = 1 enables the clock <===== we select this one + // + // CLKDIS = 0 no effect <===== take default + // CLKDIS = 1 disables the clock + // + // 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 - // TC Channel Mode Register TC_CMR (read/write) - // - // |-----------------------------------|------------|---------------| - // | LDRB LDRA | - // |-----------------------------------|------------|---------------| - // 31 19 18 17 16 - // - // |----------|---------|--------------|------------|---------------| - // |WAVE = 0 CPCTRG ABETRG ETRGEDG | - // |----------|---------|--------------|------------|---------------| - // 15 14 13 11 10 9 8 - // - // |----------|---------|--------------|------------|---------------| - // | LDBDIS LDBSTOP BURST CLKI TCCLKS | - // |----------|---------|--------------|------------|---------------| - // 7 6 5 4 3 2 0 - // - // CLOCK SELECTION - // TCCLKS = 000 TIMER_CLOCK1 (MCK/2 = 24027420 hz) - // 001 TIMER_CLOCK2 (MCK/8 = 6006855 hz) - // 010 TIMER_CLOCK3 (MCK/32 = 1501713 hz) - // 011 TIMER_CLOCK4 (MCK/128 = 375428 hz) - // 100 TIMER_CLOCK5 (MCK/1024 = 46928 hz) <===== we select this one - // 101 XC0 - // 101 XC1 - // 101 XC2 - // - // CLOCK INVERT - // CLKI = 0 counter incremented on rising clock edge <===== we select this one - // CLKI = 1 counter incremented on falling clock edge - // - // BURST SIGNAL SELECTION - // BURST = 00 clock is not gated by any external system <===== take default - // 01 XC0 is anded with the clock - // 10 XC1 is anded with the clock - // 11 XC2 is anded with the clock - // - // COUNTER CLOCK STOPPED WITH RB LOADING - // LDBSTOP = 0 counter clock is not stopped when RB loading occurs <===== take default - // = 1 counter clock is stopped when RB loading occur - // - // COUNTER CLOCK DISABLE WITH RB LOADING - // LDBDIS = 0 counter clock is not disabled when RB loading occurs <===== take default - // = 1 counter clock is disabled when RB loading occurs - // - // EXTERNAL TRIGGER EDGE SELECTION - // ETRGEDG = 00 (none) <===== take default - // 01 (rising edge) - // 10 (falling edge) - // 11 (each edge) - // - // TIOA OR TIOB EXTERNAL TRIGGER SELECTION - // ABETRG = 0 (TIOA is used) <===== take default - // 1 (TIOB is used) - // - // RC COMPARE TRIGGER ENABLE - // CPCTRG = 0 (RC Compare has no effect on the counter and its clock) - // 1 (RC Compare resets the counter and starts the clock) <===== we select this one - // - // WAVE - // WAVE = 0 Capture Mode is enabled <===== we select this one - // 1 Waveform Mode is enabled - // - // RA LOADING SELECTION - // LDRA = 00 none) <===== take default - // 01 (rising edge of TIOA) - // 10 (falling edge of TIOA) - // 11 (each edge of TIOA) - // - // RB LOADING SELECTION - // LDRB = 00 (none) <===== take default - // 01 (rising edge of TIOA) - // 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) - - // TC Register C TC_RC (read/write) Compare Register 16-bits - // - // |----------------------------------|----------------------------------------| - // | not used RC | - // |----------------------------------|----------------------------------------| - // 31 16 15 0 - // - // Timer Calculation: What count gives 1 msec time-out? - // - // TIMER_CLOCK5 = MCK / 1024 = 48054841 / 1024 = 46928 hz - // - // TIMER_CLOCK5 Period = 1 / 46928 = 21.309239686 microseconds - // - // A little algebra: .001 sec = count * 21.3092396896*10**-6 - // count = .001 / 21.3092396896*10**-6 - // count = 46.928 - // - pTC->TC_RC = 47; + // TC Channel Mode Register TC_CMR (read/write) + // + // |-----------------------------------|------------|---------------| + // | LDRB LDRA | + // |-----------------------------------|------------|---------------| + // 31 19 18 17 16 + // + // |----------|---------|--------------|------------|---------------| + // |WAVE = 0 CPCTRG ABETRG ETRGEDG | + // |----------|---------|--------------|------------|---------------| + // 15 14 13 11 10 9 8 + // + // |----------|---------|--------------|------------|---------------| + // | LDBDIS LDBSTOP BURST CLKI TCCLKS | + // |----------|---------|--------------|------------|---------------| + // 7 6 5 4 3 2 0 + // + // CLOCK SELECTION + // TCCLKS = 000 TIMER_CLOCK1 (MCK/2 = 24027420 hz) + // 001 TIMER_CLOCK2 (MCK/8 = 6006855 hz) + // 010 TIMER_CLOCK3 (MCK/32 = 1501713 hz) + // 011 TIMER_CLOCK4 (MCK/128 = 375428 hz) + // 100 TIMER_CLOCK5 (MCK/1024 = 46928 hz) <===== we select this one + // 101 XC0 + // 101 XC1 + // 101 XC2 + // + // CLOCK INVERT + // CLKI = 0 counter incremented on rising clock edge <===== we select this one + // CLKI = 1 counter incremented on falling clock edge + // + // BURST SIGNAL SELECTION + // BURST = 00 clock is not gated by any external system <===== take default + // 01 XC0 is anded with the clock + // 10 XC1 is anded with the clock + // 11 XC2 is anded with the clock + // + // COUNTER CLOCK STOPPED WITH RB LOADING + // LDBSTOP = 0 counter clock is not stopped when RB loading occurs <===== take default + // = 1 counter clock is stopped when RB loading occur + // + // COUNTER CLOCK DISABLE WITH RB LOADING + // LDBDIS = 0 counter clock is not disabled when RB loading occurs <===== take default + // = 1 counter clock is disabled when RB loading occurs + // + // EXTERNAL TRIGGER EDGE SELECTION + // ETRGEDG = 00 (none) <===== take default + // 01 (rising edge) + // 10 (falling edge) + // 11 (each edge) + // + // TIOA OR TIOB EXTERNAL TRIGGER SELECTION + // ABETRG = 0 (TIOA is used) <===== take default + // 1 (TIOB is used) + // + // RC COMPARE TRIGGER ENABLE + // CPCTRG = 0 (RC Compare has no effect on the counter and its clock) + // 1 (RC Compare resets the counter and starts the clock) <===== we select this one + // + // WAVE + // WAVE = 0 Capture Mode is enabled <===== we select this one + // 1 Waveform Mode is enabled + // + // RA LOADING SELECTION + // LDRA = 00 none) <===== take default + // 01 (rising edge of TIOA) + // 10 (falling edge of TIOA) + // 11 (each edge of TIOA) + // + // RB LOADING SELECTION + // LDRB = 00 (none) <===== take default + // 01 (rising edge of TIOA) + // 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) + // TC Register C TC_RC (read/write) Compare Register 16-bits + // + // |----------------------------------|----------------------------------------| + // | not used RC | + // |----------------------------------|----------------------------------------| + // 31 16 15 0 + // + // Timer Calculation: What count gives 1 msec time-out? + // + // TIMER_CLOCK5 = MCK / 1024 = 48054841 / 1024 = 46928 hz + // + // TIMER_CLOCK5 Period = 1 / 46928 = 21.309239686 microseconds + // + // A little algebra: .001 sec = count * 21.3092396896*10**-6 + // count = .001 / 21.3092396896*10**-6 + // count = 46.928 + // + // STK: Even Simpler, let the compiler do the work: + // + // TIMER_CLOCK5 = (MCK / 1024) / 1000 + // = 48054841 / 1024 / 1000 = 46.928 + pTC->TC_RC = ((MCK/1024/1000)+1)*milliseconds; - // TC Interrupt Enable Register TC_IER (write-only) - // - // - // |------------|-------|-------|-------|-------|--------|--------|--------|--------| - // | ETRGS LDRBS LDRAS CPCS CPBS CPAS LOVRS COVFS | - // |------------|-------|-------|-------|-------|--------|--------|--------|--------| - // 31 8 7 6 5 4 3 2 1 0 - // - // COVFS = 0 no effect <===== take default - // 1 enable counter overflow interrupt - // - // LOVRS = 0 no effect <===== take default - // 1 enable load overrun interrupt - // - // CPAS = 0 no effect <===== take default - // 1 enable RA compare interrupt - // - // CPBS = 0 no effect <===== take default - // 1 enable RB compare interrupt - // - // CPCS = 0 no effect - // 1 enable RC compare interrupt <===== we select this one - // - // LDRAS = 0 no effect <===== take default - // 1 enable RA load interrupt - // - // LDRBS = 0 no effect <===== take default - // 1 enable RB load interrupt - // - // ETRGS = 0 no effect <===== take default - // 1 enable External Trigger interrupt - // - pTC->TC_IER = 0x10; // enable RC compare interrupt + // TC Interrupt Enable Register TC_IER (write-only) + // + // + // |------------|-------|-------|-------|-------|--------|--------|--------|--------| + // | ETRGS LDRBS LDRAS CPCS CPBS CPAS LOVRS COVFS | + // |------------|-------|-------|-------|-------|--------|--------|--------|--------| + // 31 8 7 6 5 4 3 2 1 0 + // + // COVFS = 0 no effect <===== take default + // 1 enable counter overflow interrupt + // + // LOVRS = 0 no effect <===== take default + // 1 enable load overrun interrupt + // + // CPAS = 0 no effect <===== take default + // 1 enable RA compare interrupt + // + // CPBS = 0 no effect <===== take default + // 1 enable RB compare interrupt + // + // CPCS = 0 no effect + // 1 enable RC compare interrupt <===== we select this one + // + // LDRAS = 0 no effect <===== take default + // 1 enable RA load interrupt + // + // LDRBS = 0 no effect <===== take default + // 1 enable RB load interrupt + // + // ETRGS = 0 no effect <===== take default + // 1 enable External Trigger interrupt + // + pTC->TC_IER = 0x10; // enable RC compare interrupt - - // TC Interrupt Disable Register TC_IDR (write-only) - // - // - // |------------|-------|-------|-------|-------|--------|--------|--------|--------| - // | ETRGS LDRBS LDRAS CPCS CPBS CPAS LOVRS COVFS | - // |------------|-------|-------|-------|-------|--------|--------|--------|--------| - // 31 8 7 6 5 4 3 2 1 0 - // - // COVFS = 0 no effect - // 1 disable counter overflow interrupt <===== we select this one - // - // LOVRS = 0 no effect - // 1 disable load overrun interrupt <===== we select this one - // - // CPAS = 0 no effect - // 1 disable RA compare interrupt <===== we select this one - // - // CPBS = 0 no effect - // 1 disable RB compare interrupt <===== we select this one - // - // CPCS = 0 no effect <===== take default - // 1 disable RC compare interrupt - // - // LDRAS = 0 no effect - // 1 disable RA load interrupt <===== we select this one - // - // LDRBS = 0 no effect - // 1 disable RB load interrupt <===== we select this one - // - // ETRGS = 0 no effect - // 1 disable External Trigger interrupt <===== we select this one - // - pTC->TC_IDR = 0xEF; // disable all except RC compare interrupt + // TC Interrupt Disable Register TC_IDR (write-only) + // + // + // |------------|-------|-------|-------|-------|--------|--------|--------|--------| + // | ETRGS LDRBS LDRAS CPCS CPBS CPAS LOVRS COVFS | + // |------------|-------|-------|-------|-------|--------|--------|--------|--------| + // 31 8 7 6 5 4 3 2 1 0 + // + // COVFS = 0 no effect + // 1 disable counter overflow interrupt <===== we select this one + // + // LOVRS = 0 no effect + // 1 disable load overrun interrupt <===== we select this one + // + // CPAS = 0 no effect + // 1 disable RA compare interrupt <===== we select this one + // + // CPBS = 0 no effect + // 1 disable RB compare interrupt <===== we select this one + // + // CPCS = 0 no effect <===== take default + // 1 disable RC compare interrupt + // + // LDRAS = 0 no effect + // 1 disable RA load interrupt <===== we select this one + // + // LDRBS = 0 no effect + // 1 disable RB load interrupt <===== we select this one + // + // ETRGS = 0 no effect + // 1 disable External Trigger interrupt <===== we select this one + // + pTC->TC_IDR = 0xEF; // disable all except RC compare interrupt } // ***************************************************************************** -// +// // Timer 0 Interrupt Service Routine // -// entered when Timer0 RC compare interrupt asserts (200 msec period) -// blinks LED2 (pin PA2) +// Entered when Timer0 RC compare interrupt asserts // // Author: James P Lynch May 12, 2007 -// ***************************************************************************** +// Modified by Steve Karg +// simplified and changed to a millisecond count-up timer +// ***************************************************************************** void Timer0IrqHandler (void) { - - volatile AT91PS_TC pTC = AT91C_BASE_TC0; // pointer to timer channel 0 register structure - unsigned int dummy; // temporary - dummy = pTC->TC_SR; // read TC0 Status Register to clear interrupt - Timer_Milliseconds++; // increment the tick count + volatile AT91PS_TC pTC = AT91C_BASE_TC0; // pointer to timer channel 0 register structure + unsigned int dummy; // temporary + + // read TC0 Status Register to clear interrupt + dummy = pTC->TC_SR; + // increment the tick count + Timer_Milliseconds++; } void TimerInit(void) { - // enable the Timer0 peripheral clock - volatile AT91PS_PMC pPMC = AT91C_BASE_PMC; + volatile AT91PS_PMC pPMC = AT91C_BASE_PMC; pPMC->PMC_PCER = pPMC->PMC_PCSR | (1<AIC_IDCR = (1<AIC_SVR[AT91C_ID_TC0] = // Set the TC0 IRQ handler address in AIC Source - (unsigned int)Timer0IrqHandler; // Vector Register[12] - pAIC->AIC_SMR[AT91C_ID_TC0] = // Set the interrupt source type and priority - (AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE | 0x4 ); // in AIC Source Mode Register[12] - pAIC->AIC_ICCR = (1<AIC_IDCR = (0<AIC_IECR = (1<AIC_IDCR = (1<AIC_SVR[AT91C_ID_TC0] = + (unsigned int)Timer0IrqHandler; + // Set the interrupt source type and priority + // in AIC Source Mode Register[12] + pAIC->AIC_SMR[AT91C_ID_TC0] = + (AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE | 0x4 ); + // Clear the TC0 interrupt + // in AIC Interrupt Clear Command Register + pAIC->AIC_ICCR = (1<AIC_IDCR = (0<AIC_IECR = (1<