Tweaked the Atmel ARM7 MS/TP settings.

This commit is contained in:
skarg
2007-08-09 23:53:18 +00:00
parent ed5562126e
commit f1deb0b1fe
6 changed files with 301 additions and 286 deletions
+2 -2
View File
@@ -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 */
+2 -2
View File
@@ -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 {
+4 -6
View File
@@ -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)
/* LED ON */
pPIO->PIO_CODR = LED2;
else
pPIO->PIO_SODR = LED2;
}
/* only do master state machine while rx is idle */
if (MSTP_Port.receive_state == MSTP_RECEIVE_STATE_IDLE) {
+2 -1
View File
@@ -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,<options> Pass comma-separated <options> on to the assembler
AFLAGS = -Wa,-ahls,-mapcs-32,-adhlns=$(<:.s=.lst)
+13 -14
View File
@@ -38,7 +38,7 @@
#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;
}
/****************************************************************************
@@ -76,7 +76,7 @@ void RS485_Initialize(void)
AT91C_US_TXDIS; /* Transmitter Disable */
RS485_Interface->US_MR =
AT91C_US_USMODE_RS485 | /* RS-485 Mode - RTS auto asserted */
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 */
@@ -146,31 +146,25 @@ 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)
/* LED ON */
pPIO->PIO_CODR = LED1;
else
pPIO->PIO_SODR = 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++;
@@ -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;
}
+43 -26
View File
@@ -2,7 +2,7 @@
//
// 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.
//
@@ -16,9 +16,9 @@
//
// 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,6 +31,9 @@
// 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
// *****************************************************************************
@@ -43,8 +46,7 @@
// global variable counts interrupts
volatile unsigned long Timer_Milliseconds = 0;
void TimerSetup(void) {
void Timer0_Setup(int milliseconds) {
// TC Block Control Register TC_BCR (read/write)
//
// |------------------------------------------------------------------|------|
@@ -198,8 +200,11 @@ void TimerSetup(void) {
// count = .001 / 21.3092396896*10**-6
// count = 46.928
//
pTC->TC_RC = 47;
// 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)
//
@@ -235,7 +240,6 @@ void TimerSetup(void) {
//
pTC->TC_IER = 0x10; // enable RC compare interrupt
// TC Interrupt Disable Register TC_IDR (write-only)
//
//
@@ -275,36 +279,49 @@ void TimerSetup(void) {
//
// 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
// 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;
pPMC->PMC_PCER = pPMC->PMC_PCSR | (1<<AT91C_ID_TC0);
// Set up the AIC registers for Timer 0
volatile AT91PS_AIC pAIC = AT91C_BASE_AIC; // pointer to AIC data structure
pAIC->AIC_IDCR = (1<<AT91C_ID_TC0); // Disable timer 0 interrupt in AIC Interrupt Disable Command Register
pAIC->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<<AT91C_ID_TC0); // Clear the TC0 interrupt in AIC Interrupt Clear Command Register
pAIC->AIC_IDCR = (0<<AT91C_ID_TC0); // Remove disable timer 0 interrupt in AIC Interrupt Disable Command Reg
pAIC->AIC_IECR = (1<<AT91C_ID_TC0); // Enable the TC0 interrupt in AIC Interrupt Enable Command Register
// Setup timer0 to generate a 10 msec periodic interrupt
TimerSetup();
volatile AT91PS_AIC pAIC = AT91C_BASE_AIC;
// Disable timer 0 interrupt
// in AIC Interrupt Disable Command Register
pAIC->AIC_IDCR = (1<<AT91C_ID_TC0);
// Set the TC0 IRQ handler address in
// AIC Source Vector Register[12]
pAIC->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<<AT91C_ID_TC0);
// Remove disable timer 0 interrupt
// in AIC Interrupt Disable Command Reg
pAIC->AIC_IDCR = (0<<AT91C_ID_TC0);
// Enable the TC0 interrupt
// in AIC Interrupt Enable Command Register
pAIC->AIC_IECR = (1<<AT91C_ID_TC0);
// Setup timer0 to generate a 1 msec periodic interrupt
Timer0_Setup(1);
}