mlkushan
Joined: 16 Nov 2008 Posts: 22 Location: Sri Lanka
|
Problem in BYTE stream data transmission through UART |
Posted: Thu Jan 15, 2009 11:18 pm |
|
|
Hi all,
I'm doing a wireless sensor network based project. Here i needs to send a packet from source to destination. Packet format is mentioned bellow with example values for each segment of the packet and size of the each field (field, example value, size).
Destination address 0x55 1 byte
source address 0x00 1 byte
Final Destination address 0x55 1 byte
Originator Address 0x00 1 byte
Packet Type 0x00 1 byte
Hop Count 0x00 1 byte
Payload length 0x00 1 byte
Payload AA 4 byte
Ending Delimiter 0x7FF 1 byte
There is no problem in serial communication between the source and the destination. it works perfectly.
But at the destination end packet is drop by the program. due to some data modification of the packet. What i mean by modifications is the byte stream send by the sender is not captured correctly. when i send 0x00,0x00,0x00,0x00,0x00,0x00,0x00,AA,0x55,0x7FF as the byte stream. the receiver interpret it as 1010302-86-21-2. So that implies the packet has been modified.
Then the packet is drop by below mention code segment of the receiver program. If the data has been correctly transferred without any modification, "Rx_buffer[0] != Ended)" or "(Rx_buffer[0] != Broadcasts" should be true.
So I couldn't figure out the exact reason to the above mention problem.
For simplicity i post the entire code here. Sender code is a testing code which i use for testing.
So please help me to figure out the problem here while transmitting the hexadecimal values in the byte stream.
Thank you very much everyone. Any help is highly appreciated.
Kushan
Code: |
if(data_avail)
if((rx_buffer[0] != EndDevAdd01) || (rx_buffer[0] != BrdcastAdd)){
memset(rx_buffer,0,sizeof(rx_buffer)); //drop the rx packet
printf("Drp:\n"); //Print for testing purposes only
}
.........
}
|
Data Packet Transmitter code;
Code: |
#include <16F877A.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc <= 4mhz
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES WRT_50% //Lower half of Program Memory is Write Protected
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#include <stdio.h>
#include <stdlib.h>
#include <stdlibm.h>
#include <string.h>
//for routting algorithm
#define CoordntrAdd 0x00 //Defining the Address of the Coordinator
#define RouterAdd01 0x81 //Address of this Router device
#define BrdcastAdd 0xFF
#define EndDevAdd01 0x01 //Addresses of End Devices
#define EndDevAdd02 0x02 //Addresses of End Devices
//for RXTX data communication
#define RX_BUFFER_SIZE 12
#define TX_BUFFER_SIZE 12
#define DELIM 0xFE //since we are using bytes
#byte TXREG=0x19
#byte PIR1 = 0x0c
#bit TXIF=PIR1.4
//unsigned int8 rx_buffer[RX_BUFFER_SIZE + 1];
unsigned int8 tx_buffer[TX_BUFFER_SIZE + 1];
//int8 rx_wr_index = 0;
int8 tx_rd_index = 0;
int8 tx_wr_index = 0;
int8 tx_counter = 0;
//int8 rxd;
//int1 data_avail = FALSE;
#int_TBE
void TBE_isr(void) {
if (tx_counter != 0) {
putc(tx_buffer[tx_rd_index]);
if (++tx_rd_index > TX_BUFFER_SIZE) {
tx_rd_index = 0;
}
tx_counter--;
if (tx_counter == 0) {
disable_interrupts(INT_TBE);
}
}
}
void bputc(int c) {
int restart = 0;
if (tx_counter == 0) {
restart = 1;
}
tx_buffer[tx_wr_index++] = c;
if (tx_wr_index > TX_BUFFER_SIZE) {
tx_wr_index = 0;
}
tx_counter++;
if (restart == 1) {
enable_interrupts(INT_TBE);
}
}
void main(){
int8 a;
unsigned int8 packet[10];
delay_ms(2000);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
//enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(true){
packet[0] = EndDevAdd01; //destination
packet[1] = CoordntrAdd; //source
packet[2] = EndDevAdd01; //final destination
packet[3] = CoordntrAdd; //originater
packet[4] = 0x03; //packet type
packet[5] = 0x00; //hopcount
packet[6] = 0x02; //payload length
packet[7] = 0xAA; //AC on state
packet[8] = 0x15; //AC on signal
packet[9] = DELIM; //ending delimeter
for(a=0;a<10;a++){
bputc(packet[a]);
}
delay_ms(5000);
packet[0] = BrdcastAdd; //destination
packet[1] = EndDevAdd02; //source
packet[2] = BrdcastAdd; //final destination
packet[3] = EndDevAdd02; //originater
packet[4] = 0x04; //packet type
packet[5] = 0x00; //hopcount
packet[6] = 0x02; //payload length
packet[7] = 0xAA; //AC on state
packet[8] = 0x16; //AC on signal
packet[9] = DELIM; //ending delimeter
for(a=0;a<10;a++){
bputc(packet[a]);
}
delay_ms(5000);
}
}
|
Data Packet Receiver code;
Code: |
#include <16F877A.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc <= 4mhz
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES WRT_50% //Lower half of Program Memory is Write Protected
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#include <math.h>
#include <stdlibm.h>
#include <string.h>
//function prototypes
void sendData(int8 envTemp, int8 packetType, int8 *packet);
void payloadDecipher(unsigned int num_rounds, unsigned int8* packetPayload);
void payloadEncipher(unsigned int num_rounds, unsigned int8* packetPayload);
void createPacket(int8 packetType, int8 payloadLength, int8 *packet);
//For encryption and decryption
unsigned int8 key[] = {0x80, 0x00, 0x80, 0x80}; //32bit int8 key of for XTEA
//define the packet payload array pointer
int8 *packetPayload;
//Array for keeping routing entries
//route_table[0] for keeping the nexthop address
//route_table[1] for keeping the hopcount
int8 route_table[2];
//mainteains the Air Conditioner state
int1 AC_State = FALSE;
//for RXTX data communication
#define RX_BUFFER_SIZE 12
#define TX_BUFFER_SIZE 12
#define DELIM 0xFE //since we are using bytes
#byte TXREG=0x19
#byte PIR1 = 0x0c
#bit TXIF=PIR1.4
unsigned int8 rx_buffer[RX_BUFFER_SIZE + 1];
unsigned int8 tx_buffer[TX_BUFFER_SIZE + 1];
int8 rx_wr_index = 0;
int8 tx_rd_index = 0;
int8 tx_wr_index = 0;
int8 tx_counter = 0;
int8 rxd;
int1 data_avail = FALSE;
//Define AC state
#define ACStateON 0xAA
#define ACStateOFF 0xBB
//for routting algorithm
#define CoordntrAdd 0x00 //Defining the Address of the Coordinator
#define RouterAdd01 0x81 //Address of this Router device
#define EndDevAdd01 0x01 //Addresses of End Devices
#define BrdcastAdd 0xFF
//SPI communication parameters
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H) // low leading edge
#define SPI_MODE_1 (SPI_L_TO_H) // low trailing edge
#define SPI_MODE_2 (SPI_H_TO_L) // high leading edge
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H) // high trailing edge
#int_RDA
void RDA_isr(void) {
rx_buffer[rx_wr_index] = getc();
rxd = rx_buffer[rx_wr_index];
rx_wr_index++;
if(rxd==DELIM){
data_avail = TRUE;
rx_wr_index = 0;
}
if (rx_wr_index > RX_BUFFER_SIZE) { //prevent buffer overflows
rx_wr_index = 0;
}
}
#int_TBE
void TBE_isr(void) {
if (tx_counter != 0) {
putc(tx_buffer[tx_rd_index]);
if (++tx_rd_index > TX_BUFFER_SIZE) {
tx_rd_index = 0;
}
tx_counter--;
if (tx_counter == 0) {
disable_interrupts(INT_TBE);
}
}
}
void bputc(int c) {
int restart = 0;
if (tx_counter == 0){
restart = 1;
}
tx_buffer[tx_wr_index++] = c;
if (tx_wr_index > TX_BUFFER_SIZE) {
tx_wr_index = 0;
}
tx_counter++;
if (restart == 1){
enable_interrupts(INT_TBE);
}
}
void setIrCommand(int8 ACState, int8 tempValue){
if(ACState == ACStateON){
spi_write(0x32); //set AC ON
}
else if(ACState == ACStateOFF){
spi_write(0x64); //set AC OFF
}
else if((tempValue > 0x16) && (tempValue < 0x31)){
spi_write(tempValue); //set temperature value here.
}
}
void main(){
int8 pwmDuty = 50;
int8 counter = 0;
int8 envTemp;
int8 *rxPcketPayload;
int8 a;
int8 packet[12];
//delay_ms(2000); //initializing delay
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
//set_tris_a(0b00000001);
setup_psp(PSP_DISABLED);
delay_us(100); //This ensures the slave has time to wake before master
setup_spi(SPI_MASTER|SPI_MODE_0|SPI_CLK_DIV_4);
delay_us(100);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_1,24,1);
setup_ccp1(CCP_PWM);
set_pwm1_duty(pwmDuty);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
route_table[1] = 0xFF; // First initialise the hop count to the largest value.
while(true){
//packet listener code
if(data_avail)
{
data_avail = FALSE;
printf("DA:%d\n",rx_buffer[4]); //Print for testing purposes only
if((rx_buffer[0] != EndDevAdd01) || (rx_buffer[0] != BrdcastAdd)){
memset(rx_buffer,0,sizeof(rx_buffer)); //drop the rx packet
printf("Drp:\n"); //Print for testing purposes only
}
else{
switch(rx_buffer[4]){ // switch the packet type
case 0x01: // Route request packet
if(route_table[1] > rx_buffer[5]){ //check the hop count value of the incoming packet
route_table[0] = rx_buffer[1]; // Nearest source's address
route_table[1] = rx_buffer[5]; // update the hop count
}
printf("Rqst:\n"); //Print for testing purposes only
createPacket(0x02, 0x00, packet); // Send a route reply packet
break;
case 0x02: // Route reply packet, from others, shold be droped
printf("Othr:\n"); //Print for testing purposes only
// Drop the packet
break;
case 0x03: // Data packet from the cordinator
rxPcketPayload = (int8 *)calloc(rx_buffer[6], sizeof(int8)); //allocate memory of the size of incoming packet payload length to store the incoming data
for(a = 0; a < rx_buffer[6]; a++){
*(rxPcketPayload + a) = rx_buffer[(7 + a)]; //store the payload into rxPcketPayload
}
for(a = 0; a < rx_buffer[6]; (a += 2)){
payloadDecipher(32,(rxPcketPayload + a)); //decrypt the packet here
}
//first byte of the payload is the ACState and the second byte of the payload is the tempValue
setIrCommand(*rxPcketPayload, *(rxPcketPayload + 1));
free(rxPcketPayload); //free the alocated memory
printf("Data:\n"); //Print for testing purposes only
break;
case 0x04: // Emergency
set_adc_channel(0); //the next read_adc call will read channel0. This is needed when there are more analog inputs
envTemp = read_adc() * 500/1024;
envTemp = floor(envTemp);
printf("Emrg:\n"); //Print for testing purposes only
sendData(envTemp, 0x04, packet); //send emergency data packet
break;
}
memset(rx_buffer,0,sizeof(rx_buffer));
}
}
//End of packet listener code
else if(counter == 60){ //if the counter equals to 2000 it reads the temperature value from the sensor
counter = 0; //Again set the counter to zero
set_adc_channel(0); //the next read_adc call will read channel0. This is needed when there are more analog inputs
envTemp = read_adc() * 500/1024;
envTemp = floor(envTemp);
sendData(envTemp, 0x03, packet); //send data packet to the cordianter which contains environment temperature
}
delay_ms(500);
counter++; //set the counter here as a timer
}
}
void payloadEncipher(unsigned int num_rounds, unsigned int8* packetPayload){
unsigned int8 fblock, sblock, i, sum=0;
unsigned int8 delta=0x9E3779B9;
fblock = *packetPayload;
sblock = *(packetPayload + 1);
for(i=0; i<num_rounds; i++) {
fblock += (((sblock << 4) ^ (sblock >> 5)) + sblock) ^ (sum + key[sum & 3]);
sum += delta;
sblock += (((fblock << 4) ^ (fblock >> 5)) + fblock) ^ (sum + key[(sum>>11) & 3]);
}
*packetPayload = fblock;
*(packetPayload + 1) = sblock;
}
void payloadDecipher(unsigned int num_rounds, unsigned int8* packetPayload) {
unsigned int8 fblock, sblock, i, sum;
unsigned int8 delta=0x9E3779B9;
fblock = *packetPayload;
sblock = *(packetPayload + 1);
sum=delta*num_rounds;
for(i=0; i<num_rounds; i++) {
sblock -= (((fblock << 4) ^ (fblock >> 5)) + fblock) ^ (sum + key[(sum>>11) & 3]);
sum -= delta;
fblock -= (((sblock << 4) ^ (sblock >> 5)) + sblock) ^ (sum + key[sum & 3]);
}
*packetPayload = fblock;
*(packetPayload + 1) = sblock;
}
// Function to create the data packet
void createPacket(int8 packetType, int8 payloadLength, int8 *packet){
int8 a = 0;
if(packetType == 0x04){ //for emergencey packet
packet[0] = BrdcastAdd; //add the broadcast address to send the packet
}
else{ //for normal data packet or router reply packet (sends to the cordinator)
packet[0] = route_table[0]; //add the nearest destination address to send the packet
}
packet[1] = EndDevAdd01; //add the source address to the packet
packet[2] = CoordntrAdd; //add the final destination address(cordinator)
packet[3] = EndDevAdd01; //add the originator node address to the packet
packet[4] = packetType; //set the packet type here
packet[5] = 0x00; //set the hop count here
packet[6] = payloadLength; //add the payload length to the packet
if(payloadLength != 0x00){
for(a = 0; a < payloadLength; a++){
packet[a + 7] = *(packetPayload + a); //add the payload to the packet here
}
}
packet[payloadLength + 7] = DELIM; //add the delimeter to the end of the packet
for (a=0;a < (8 + payloadLength) ;a++){ //send the packet data
bputc(packet[a]);
}
}
// Sending data
void sendData(int8 envTemp, int8 packetType, int8 *packet){
int8 payloadLength = 0x00; //set the payload length
int8 a;
packetPayload = (int8 *)calloc(4, sizeof(int8)); //allocate memory for the packet payload
if(AC_State){
*(packetPayload + 0) = ACStateON; //AC is in on state
payloadLength++;
} else {
*(packetPayload + 0) = ACStateOFF; //AC is in off state
payloadLength++;
}
*(packetPayload + 1) = envTemp; //here temperature values sholud be assigned
payloadLength++;
//payload length should be an even number
for(a = 0; a < payloadLength; (a += 2)){
payloadEncipher(32, (packetPayload + a)); //encrypt the packet payload here
}
if(packetType == 0x03){
createPacket(0x03, payLoadLength, packet); //send data packet
}
else if(packetType == 0x04){
createPacket(0x04, payLoadLength, packet); //send emergency data packet
}
free(packetPayload); //free the memory, allocated for the packet payload
}
|
_________________ Kushan Sharma
mlkushan@gmail.com |
|