CHAPTER 7 CONCLUSION
C.4 Robot Station RCP Code
PORTB.3 = 1;
for (i = 0; i <= 17; i++) {
printf ("%c",Txarr[i]);
} PORTB.1 = 1;
if (Txarr[1] == toascii(51)) csel = 1;
Rx = Rx - 1;
time = 0;
x = 0;
} }
else if ((Rarr[1] == toascii(51)) || (Rarr[1] == toascii(52))) {
csel = 1;
PORTB.2 = 1;
PORTB.3 = 0;
//*****output to app layer i = 17;
printf ("@");
while (Rarr[i-1] != toascii(37)) {
printf ("%c",Rarr[i]);
i++;
} printf ("%%");
Rx = Rx - 1;
} };
}
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC) // USART Receiver buffer
#define RX_BUFFER_SIZE 8 char rx_buffer[RX_BUFFER_SIZE];
unsigned char rx_wr_index,rx_rd_index,rx_counter;
// This flag is set on USART Receiver buffer overflow bit rx_buffer_overflow;
// USART Receiver interrupt service routine
#pragma savereg-
interrupt [USART_RXC] void uart_rx_isr(void) {
char status,data;
#asm push r26 push r27 push r30 push r31 in r26,sreg push r26
#endasm status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) {
rx_buffer[rx_wr_index]=data;
if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if (++rx_counter == RX_BUFFER_SIZE) {
rx_counter=0;
rx_buffer_overflow=1;
};
};
#asm pop r26 out sreg,r26 pop r31 pop r30 pop r27 pop r26
#endasm
if (csel == 1) {
//Identify the first byte of data stream if (data == toascii(35))
{ pos = 0;
arR[pos] = data;
} else
//verify that the packet is meant for this station, if not, delay for packet transmission duration {
pos = pos + 1;
arR[pos] = data;
} if (pos == 10) { x = 0;
for (i = 0; i <= 5; i++) {
if (callsign[i] == arR[i + 4]) x++;
} if (x != 6) {
delay_ms (7 * (arR[2] + arR[3]));
//printf ("x %d",x);
} }
//check for the last byte, and if so, verify the packets contents with the Checksum byte.
if ((data == toascii(33)) && (x == 6))//'!' {
cksmR = 35;
while ((cksmR == 35) || (cksmR == 33) || (isprint (cksmR) != 1)) {
cksmR = 0;
for (i = 0; i <= (pos - 2); i++) {
cksmR = fmod((arR[i] + cksmR),94);
}
cksmR = cksmR + 32;
if ((cksmR == 35) || (cksmR == 33) || (isprint (cksmR) != 1)) arR[2]++;
}
//Confirm validation of packet so that the reply packet can be sent if (cksmR == arR[pos - 1]) Rvalid = 1;
else {
Rvalid = 0;
Rx++;
} } tx1 = 0;
} else {
if (data == toascii(64)) // '@' {
Datalength = 0;
pos = 0;
arR[pos] = data;
} else { pos++;
Datalength++;
arR[pos] = data;
} } }
#pragma savereg+
#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void) {
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#asm("cli") --rx_counter;
#asm("sei") return data;
}
#pragma used-
#endif
// USART Transmitter buffer
#define TX_BUFFER_SIZE 8 char tx_buffer[TX_BUFFER_SIZE];
unsigned char tx_wr_index,tx_rd_index,tx_counter;
// USART Transmitter interrupt service routine
#pragma savereg-
interrupt [USART_TXC] void uart_tx_isr(void) {
#asm push r26 push r27 push r30 push r31 in r26,sreg push r26
#endasm if (tx_counter) { --tx_counter;
UDR=tx_buffer[tx_rd_index];
if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
};
#asm pop r26 out sreg,r26 pop r31 pop r30 pop r27 pop r26
#endasm }
#pragma savereg+
#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c) {
while (tx_counter == TX_BUFFER_SIZE);
#asm("cli")
if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0)) {
tx_buffer[tx_wr_index]=c;
if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
++tx_counter;
} else UDR=c;
#asm("sei") }
#pragma used-
#endif
void main(void) {
short int pause = 1, sdata = 0;
// Input/Output Ports initialization // Port A initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In // State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func0=In Func1=Out Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In // State0=T State1=0 State2=T State3=T State4=T State5=T State6=T State7=T PORTB=0x00;
DDRB=0xFF;
// Port C initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In // State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In // State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T PORTD=0x00;
DDRD=0x00;
// Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped // Mode: Normal top=FFh // OC0 output: Disconnected TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off // Input Capture on Falling Edge TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2 output: Disconnected ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization // INT0: Off
// INT1: Off // INT2: Off GICR|=0x00;
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity // USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous // USART Baud rate: 1200 UCSRA=0x00;
UCSRB=0xD8;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0xBF;
// Analog Comparator initialization // Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off // Analog Comparator Output: Off
ACSR=0x80;
SFIOR=0x00;
// I2C Bus initialization i2c_init();
// Global enable interrupts
#asm("sei") Ttype = toascii(79);
while (1) { if (csel == 1) {
// Copy aRr array to rarR array and clear the arR array for (i = 0; i <= pos; i++)
{
Rarr [i] = arR[i];
arR[i] = toascii(32);
if (((Ttype == toascii(67)) && (Rarr[1] == toascii(50))) || (Rarr[1] == toascii(51))) {
csel = Rarr[18];
pause = 0;
} } } else {
// Copy ArR array to Appdata and clear arR array and make csel = 1 when a '%' is reached for (i = 0; i <= pos; i++)
{
appdata[i] = arR[i];
if (arR[i] == toascii(37)) csel = 1;
arR[i] = toascii(32);
} Ttype = appdata[1];
sdata = 1;
}
//If received packet is valid and transmission has to occur, then create packet to be transmitted.
if (((((x == 6) && (Rvalid == 1)) && ((Rarr[1] != toascii(51)) || (Rarr[1] != toascii(50)))) || (txagain == 1) || (sdata == 1)) && (tx1 == 0)) {
//byte 0 - start byte Txarr[0] = toascii (35); //'#' PORTB = 0xFF;
//byte 1 - type of packet
if (Rarr[1] == toascii(48)) Txarr[1] = toascii(49);
else if (Rarr[1] == toascii(49)) {
if (Ttype == toascii(79)) Txarr[1] = toascii(51);
else if (Ttype == toascii(67)) Txarr[1] = toascii(52);
}
else if (Rarr[1] == toascii(52)) Txarr[1] = toascii(50);
//restart transmission if timeout occured.
if ((txagain == 1) || (sdata == 1)) Txarr[1] = toascii(48);
PORTB.5 = 1;
// Validate the duration of packet
if (sdata == 1) { sdata = 0;
tx1 = 1;
if (Ttype == toascii(79)) {
if ((Datalength + 54) > 127) {
Txarr[2] = toascii (54 + Datalength - 127);
Txarr[3] = toascii(127);
} else {
Txarr[2] = toascii(32);
Txarr[3] = toascii(54 + Datalength);
} }
else if (Ttype == toascii(67)) {
if ((Datalength + 72) > 127) {
Txarr[2] = toascii (72 + Datalength - 127);
Txarr[3] = toascii (127);
} else {
Txarr[2] = toascii (32);
Txarr[3] = toascii (72 + Datalength);
} } } else {
if ((Rarr[2] + Rarr[3] - 18) > 127) {
Txarr[2] = toascii(Rarr[2] + Rarr[3] - 18 - 127);
Txarr[3] = toascii(127);
} else {
Txarr[2] = toascii(32);
Txarr[3] = toascii(Rarr[2] + Rarr[3] - 18);
} } PORTB.6 = 1;
//if the duration fields contain a # or ! then add to the first field and subtract the second field.
while ((Txarr[2] == toascii(35)) || (Txarr[2] == toascii(33)) || (Txarr[3] == toascii(35)) || (Txarr[3] == toascii(33))) {
Txarr[3] = toascii(Txarr[3] + 1);
Txarr[2] = toascii(Txarr[2] - 1);
}
//if the duration field contain non-printable characters then increment that field while ((isprint(Txarr[2]) != 1) || (isprint(Txarr[3]) != 1))
{
if (isprint(Txarr[2]) != 1) Txarr[2]++;
if (isprint(Txarr[3]) != 1) Txarr[3]++;
} PORTB.7 = 1;
//insert callsign of the station that transmitted to this station for (i = 4; i <= 9; i++) Txarr[i] = othercallsign[i - 4];
//insert the callsign of this station
for (i = 10; i <= 15; i++) Txarr[i] = callsign[i - 10];
cksmT = toascii(35);
//insert data if this is a type 3 or type 4 packet if ((Txarr[1] == toascii(51)) || (Txarr[1] == toascii(52))) {
for (i = 16; i <= (Datalength - 2); i++) Txarr[i] = appdata[i-14];
} //generate the checksum byte
cksmT = 35;
if ((Txarr[1] == 51) || (Txarr[1] == 52)) {
while ((cksmT == 35) || (cksmT == 33) || (isprint (cksmT) != 1)) {
cksmT = 0;
for (i = 0; i <= 15 + Datalength - 1; i++) {
cksmT = fmod((Txarr[i] + cksmT),94);
}
cksmT = cksmT + 32;
if ((cksmT == 35) || (cksmT == 33) || (isprint (cksmT) != 1)) Txarr[2]++;
} }
else if ((Txarr[1] == 48) || (Txarr[1] == 49) || (Txarr[1] == 50)) {
while ((cksmT == 35) || (cksmT == 33) || (isprint (cksmT) != 1)) {
cksmT = 0;
for (i = 0; i <= 15 ; i++) {
cksmT = fmod((Txarr[i] + cksmT),94);
}
cksmT = cksmT + 32;
if ((cksmT == 35) || (cksmT == 33) || (isprint (cksmT) != 1)) Txarr[2]++;
} } //checksum field
Txarr[16 + Datalength] = toascii(cksmT);
//End byte
Txarr[17 + Datalength] = toascii(33);
//for (i = 0; i<=17; i++) // {
// printf ("%c",Txarr[i]);
// }
//verify if other stations are transmitting. if not transmit //activate transmitter into tx mode PORTB.1 = 0;
if ((Txarr[1] == toascii(51)) || (Txarr[1] == toascii(52)))
{
PORTB.1 = 0;
PORTB.2 = 1;
PORTB.3 = 0;
PORTB.4 = 0;
for (i = 0; i <= (17 + Datalength); i++) {
printf ("%c",Txarr[i]);
} PORTB.1 = 1;
Rx = Rx - 1;
time = 0;
x = 0;
}
else if ((Txarr[1] == toascii(48)) || (Txarr[1] == toascii(49)) || (Txarr[1] == toascii(50))) {
PORTB.1 = 0;
PORTB.2 = 1;
PORTB.3 = 0;
PORTB.4 = 0;
for (i = 0; i <= 17; i++) {
printf ("%c",Txarr[i]);
} PORTB.1 = 1;
Rx = Rx - 1;
time = 0;
x = 0;
} }
else if (((Rarr[1] == toascii(51)) || (Rarr[1] == toascii(52))) && (pause == 0)) {
//*****output to app layer csel = Rarr[18];
if (csel == 2) {
PORTB.2 = 0;
PORTB.3 = 1;
PORTB.4 = 0;
} else {
PORTB.2 = 0;
PORTB.3 = 0;
PORTB.4 = 1;
} i = 17;
printf ("@");
while (Rarr[i] != toascii(37)) {
printf ("%c",Rarr[i]);
i++;
}
printf ("%c", toascii(37));
while (arR[pos] != toascii(37)) {
}
for (i = 0; i <= Datalength; i++) {
appdata[i] = arR[i];
}
Rx = Rx - 1;
pause = 1;
} };
}