Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12600 Discussions

RS-422 to RS-232 Conversion

Altera_Forum
Honored Contributor II
1,325 Views

Hello Friends, 

 

I am trying to convert RS-422 data (arrive at 1 mbps) from remote machine in to a RS-232 format. 

 

remote machine/system send RS-422 data (CLK+, CLK-, DATA+ and DATA-) toward NIOS-2 system. 

 

i am sending a image of 640x460 from remote machine in RS-422 format toward nios2. 

and insert sync word (192,92,51) at first three location. 

 

at receiver end First i Cheque this data for sync word (194,92,51) and also convert it in to serial to parallel data format (DATA[7..0]), using sync_detect module, if sync word found it assert HIGH on strt pulse. 

 

output of sync_detect is "nios2_output_INT" attached , seen on logic analyzer 

 

i insert sync word on first 3 position in place of 0,1, and 2 (Please see the attached Document's) 

 

if sync word is there then i read data and generate Load pulse at every 8 clock, this load pulse given to NIOS_2 which treat it as interrupt. 

 

On arriving this interrupt nios read parallel data and store it in 2D-Array of size 640x460 (as Received data contain image data). 

 

Data Contain a sequence of 0 to 255 just for testing purpose. 

 

now problem is nios miss few data or interrupt pulse can not sync with arriving 1 mbps data , it loose few data and some time repeat data 

 

output of nios2 processor reflect on attached "received data.jpj" 

below is the peace of code which i use for this conversion 

 

 

 

PKtCount =460; 

 

while(edge_capture2) //Indicate Start of Pulse 

edge_capture2 = 0; 

LPktCount = 0; 

Count = 0; 

DataCount = 0; 

do 

if(edge_capture) //w.r.t. clock or LOAD PULSE 

edge_capture = 0; //reset generated interrupt 

ImgBuff[LPktCount][Count] = IORD_ALTERA_AVALON_PIO_DATA(DATA_IN_BASE); 

Count++; 

if(Count == PktSize) //check end of packet-data -->640 

Count = 0; //Point to Start of packet data 

LPktCount++; //Increment packet Count 

 

}while(LPktCount != (PktCount+1)); 

 

Regards  

kaushal
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
443 Views

If your data is arriving at 1Mbit/sec and your nios is running at 100MHz and you have 800 clocks/byte (1000 if async data with start/stop bits). 

That doesn't make it impossible - but you definitely don't want any other interrupts in your system. 

I can't see where your code 'spins' waiting for data. 

You might need to get a trace centered on the duplicate value (maybe trigger from a write from the copy-loop).
0 Kudos
Altera_Forum
Honored Contributor II
443 Views

hello there, 

 

below is my complete code for reading 1 mbps RS-422 data and simultaneously store in 2D array. 

 

my output data stream remain same....read same data four time. despite of reading only for one time using interrupt... 

#include <stdio.h> # include <string.h> # include <ctype.h> /* RS232 Related Files....*/ # include "alt_types.h" # include "altera_avalon_pio_regs.h" # include "sys/alt_irq.h" # include "system.h" # include <unistd.h> /* MicroC/OS-II definitions */ # include "includes.h" /* Simple Socket Server definitions */ # include "simple_socket_server.h" /* Nichestack definitions */ # include "ipport.h" # include "tcpport.h" # define HIGH 1 # define LOW 0 int CheckSync(int RxSync,int IndexRxSync); int CheckReset(int RxResetSync,int IndexRxResetSync); /* A variable to hold the value of the button pio edge capture register. */ volatile int edge_capture; volatile int edge_capture2; # define client_port 90 # define client_addr "192.168.1.207" //2nd Nios-2 Board RS-422 Conversion----Tx TCP Image # define server_port 80 # define server_addr "192.168.1.66" //Linux Machine ....Image Server # define PktSize 640//1920 //1920 # define PktCount 400//1000//1080 unsigned int mPktSize = 640;//397; unsigned int mPktCount = 420;//288; unsigned int Xstart = 0; //397; to be added in mPktSize (640) 640+640=1280 //MUST BE LESS THEN 1280 unsigned int Ystart = 0; //460; to be added in mPktCount(450) 450+420=870 //MUST BE LESS THEN 440 unsigned char ImgBuff; int strt_sync = {164,92,51}; int end_sync = {235,144,3,30}; static void handle_strt_interrupts(void* context2, alt_u32 id) { volatile int* edge_capture_ptr2 = (volatile int*) context2; *edge_capture_ptr2 = IORD_ALTERA_AVALON_PIO_EDGE_CAP(STRT_OUT_BASE); IOWR_ALTERA_AVALON_PIO_EDGE_CAP(STRT_OUT_BASE, 0); IORD_ALTERA_AVALON_PIO_EDGE_CAP(STRT_OUT_BASE); } static void handle_load_interrupts(void* context, alt_u32 id) { volatile int* edge_capture_ptr = (volatile int*) context; *edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_BASE); IOWR_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_BASE, 0); IORD_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_BASE); } //------------------Function to Send Data Bytes To Remote Machine (NIOS_II)---------------- //n32sendFd :: this is socket identifier //chLocalBuffer :: this is the local buffer used by socket to send data //n32RemainingBytes :: total no of bytes left after each iteration //n32BytesSend :: bytes send fnSendFunc(int n32sendFd, char* chLocalBuffer, unsigned int n32RemainingBytes, unsigned int n32BytesSend) { unsigned int n32Send=0; while (n32RemainingBytes>0) { if ((n32Send = send(n32sendFd, chLocalBuffer+n32BytesSend, n32RemainingBytes, 0))<=0) { perror ("DMS fnSendFunc:send call"); close(n32sendFd); return(perror); } n32BytesSend += n32Send; n32RemainingBytes -= n32Send; } return (n32BytesSend); } void SSSSimpleSocketServerTask() { int sockfd; int rc,s1; int LPktCount = 0,Count =0;//,mycount =0; struct sockaddr_in servaddr,cliaddr; unsigned int DataCount = 0; void* edge_capture_ptr = (void*) &edge_capture; void* edge_capture_ptr2 = (void*) &edge_capture2; unsigned char test = 0; ssize_t addrlen; addrlen = sizeof(servaddr); /* Enable LOAD interrupts. */ IOWR_ALTERA_AVALON_PIO_IRQ_MASK(LOAD_BASE, 0x1); /* Reset the edge capture register. */ IOWR_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_BASE, 0x0); alt_ic_isr_register(LOAD_IRQ_INTERRUPT_CONTROLLER_ID, LOAD_IRQ,handle_load_interrupts, edge_capture_ptr, 0x0); /* Enable all 4 button interrupts. */ IOWR_ALTERA_AVALON_PIO_IRQ_MASK(STRT_OUT_BASE, 0xF); /* Reset the edge capture register. */ IOWR_ALTERA_AVALON_PIO_EDGE_CAP(STRT_OUT_BASE, 0x0); alt_ic_isr_register(STRT_OUT_IRQ_INTERRUPT_CONTROLLER_ID, STRT_OUT_IRQ,handle_strt_interrupts, edge_capture_ptr2, 0x0); IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0xFF); // RS232 Port Initialization FILE* fp; fp = fopen ("/dev/uart", "rb+"); //Open file for reading and writing if(fp<0) printf("RS232 Opening Error.!!\n"); else printf("RS232 Port Open....!!\n"); printf("\n\t\t\tReady to Receive Serial data From remote Synchronous System\n"); LPktCount = 0; Count = 0; fflush(stdin); fflush(stdout); edge_capture = 0; edge_capture2 = 0; while(1) { while(edge_capture2) //w.r.t. Start { edge_capture2 = 0; LPktCount = 0; Count = 0; DataCount = 0; do { if(edge_capture) //w.r.t. clock { edge_capture = 0; //reset generated interrupt ImgBuff = IORD_ALTERA_AVALON_PIO_DATA(DATA_IN_BASE); Count++; if(Count == PktSize) //check end of packet-data -->640 { Count = 0; //Point to Start of packet data LPktCount++; //Increment packet Count } } }while(LPktCount != (PktCount)); printf("\n\t#Count = %d\t LPktCount = %d",Count,LPktCount); printf("\n\t#Synchronous Data received...!!"); printf("\n\t#Sending Data at RS232 Port at 115kbps...\n"); IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0xF0); printf("\n\t# Send Sync Word.."); for(Count = 0; Count<=2;Count++) { fprintf(fp,"%c",strt_sync);//Data); printf("\t%d",strt_sync); } printf("\n"); Xstart = 0; Ystart = 0; LPktCount = 0;//mPktCount+Ystart for(LPktCount = 0+Ystart; LPktCount<mPktCount;LPktCount++) { for(DataCount = 0; DataCount<mPktSize;DataCount++) { fprintf(fp,"%c",ImgBuff); } printf(">"); } LPktCount = 0; Count = 0; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0xFC); printf("\n\t#Send Done....\n\t#Ready to receive Data.\n"); } } printf("\n\t\t\tConnection Closed ..."); close(sockfd); fclose(fp); printf("\n STRT_OUT = %d\n LOAD = %d",edge_capture,edge_capture2); } //Close Simple_SOcket_Server int CheckSync(int RxSync,int IndexRxSync) { int SyncWord = {164,92,51}; int count; int MatchCount = 0; for(count = 0;count<3;count++) { if(RxSync == SyncWord) MatchCount++; IndexRxSync = (IndexRxSync + 1) % 3; } if(MatchCount == 3) return 1; else return 0; }
0 Kudos
Altera_Forum
Honored Contributor II
443 Views

If you want us to read code, you need to wrap it in CODE tags so that the indentation isn't lost.

0 Kudos
Altera_Forum
Honored Contributor II
443 Views

Aim of this Code is to read 1 mbps RS232 (serial data) Data and store it on internal FPGA memory (2D-Array) 

 

Serial data first Converted in to Parallel format (8 bit word), parallel data available at every eight clock which i use as an interrupt so that processor can read this 8 bit word and store in imgbuff[][]
0 Kudos
Altera_Forum
Honored Contributor II
443 Views

You'd make life easier for the software timings if you added a small fifo into the hardware. And also (maybe) treat the data as 32bit. 

 

Depending on any other tasks you expect to perform, using interrupts at all may be ill advised. A simply spin/delay loop is more likely to have less problems. 

 

It is often the case that it is best to run small embedded systems without any interrupts at all. Just check each possible event source (etc) often enough. 

 

In this case get the non-interrupt version working first.
0 Kudos
Altera_Forum
Honored Contributor II
443 Views

Hello There, 

 

I have follow the suggestion's w.r.t to your previous post. 

 

1.Making data 32 bit. 

2. trying non-interrupt version. 

3.added a small fifo into the hardware (i do not know how do i do this --please suggest me

 

i had tried the non-interrupt version of my Code (Below), but still didn't get proper data (sequence of 1,2,3....255) 

 

# include <stdio.h> # include <string.h> # include <ctype.h> /* RS232 Related Files....*/ # include "alt_types.h" # include "altera_avalon_pio_regs.h" # include "sys/alt_irq.h" # include "system.h" # include <unistd.h> /* MicroC/OS-II definitions */ # include "includes.h" /* Simple Socket Server definitions */ # include "simple_socket_server.h" /* Nichestack definitions */ # include "ipport.h" # include "tcpport.h" # define HIGH 1 # define LOW 0 int CheckSync(int RxSync,int IndexRxSync); int CheckReset(int RxResetSync,int IndexRxResetSync); /* A variable to hold the value of the button pio edge capture register. */ volatile int edge_capture; volatile int edge_capture2; # define client_port 90 # define client_addr "192.168.1.207" //2nd Nios-2 Board RS-422 Conversion----Tx TCP Image # define server_port 80 # define server_addr "192.168.1.66" //Linux Machine ....Image Server # define PktSize 640//1920 //1920 # define PktCount 400//1000//1080 unsigned int mPktSize = 640;//397; unsigned int mPktCount = 420;//288; unsigned int Xstart = 0; //397; to be added in mPktSize (640) 640+640=1280 //MUST BE LESS THEN 1280 unsigned int Ystart = 0; //460; to be added in mPktCount(450) 450+420=870 //MUST BE LESS THEN 440 unsigned char ImgBuff; int strt_sync = {164,92,51}; int end_sync = {235,144,3,30}; /* static void handle_load_interrupts(void* context, alt_u32 id) { volatile int* edge_capture_ptr = (volatile int*) context; *edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_BASE); IOWR_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_BASE, 0); IORD_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_BASE); } static void handle_strt_interrupts(void* context2, alt_u32 id) { volatile int* edge_capture_ptr2 = (volatile int*) context2; *edge_capture_ptr2 = IORD_ALTERA_AVALON_PIO_EDGE_CAP(STRT_OUT_BASE); IOWR_ALTERA_AVALON_PIO_EDGE_CAP(STRT_OUT_BASE, 0); IORD_ALTERA_AVALON_PIO_EDGE_CAP(STRT_OUT_BASE); } */ //------------------Function to Send Data Bytes To Remote Machine (NIOS_II)---------------- //n32sendFd :: this is socket identifier //chLocalBuffer :: this is the local buffer used by socket to send data //n32RemainingBytes :: total no of bytes left after each iteration //n32BytesSend :: bytes send fnSendFunc(int n32sendFd, char* chLocalBuffer, unsigned int n32RemainingBytes, unsigned int n32BytesSend) { unsigned int n32Send=0; while (n32RemainingBytes>0) { if ((n32Send = send(n32sendFd, chLocalBuffer+n32BytesSend, n32RemainingBytes, 0))<=0) { perror ("DMS fnSendFunc:send call"); close(n32sendFd); return(perror); } n32BytesSend += n32Send; n32RemainingBytes -= n32Send; } return (n32BytesSend); } void SSSSimpleSocketServerTask() { int sockfd; int rc,s1; int LPktCount = 0,Count =0; struct sockaddr_in servaddr,cliaddr; unsigned int DataCount = 0; void* edge_capture_ptr = (void*) &edge_capture; void* edge_capture_ptr2 = (void*) &edge_capture2; int load = 0, strt_out = 0; ssize_t addrlen; addrlen = sizeof(servaddr); /*---------------------------------- // Enable 1 bit LOAD interrupts. IOWR_ALTERA_AVALON_PIO_IRQ_MASK(LOAD_BASE, 0x1); // Reset the edge capture register. IOWR_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_BASE, 0x0); alt_ic_isr_register(LOAD_IRQ_INTERRUPT_CONTROLLER_ID, LOAD_IRQ,handle_load_interrupts, edge_capture_ptr, 0x0); // Enable 1 bit STRT_OUT interrupts. IOWR_ALTERA_AVALON_PIO_IRQ_MASK(STRT_OUT_BASE, 0x1); // Reset the edge capture register. //IOWR_ALTERA_AVALON_PIO_EDGE_CAP(STRT_OUT_BASE, 0x0); alt_ic_isr_register(STRT_OUT_IRQ_INTERRUPT_CONTROLLER_ID, STRT_OUT_IRQ,handle_strt_interrupts, edge_capture_ptr2, 0x0); IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0xFF); */ //--------------------------- // RS232 Port Initialization FILE* fp; fp = fopen ("/dev/uart", "rb+"); //Open file for reading and writing if(fp<0) printf("RS232 Opening Error.!!\n"); else printf("RS232 Port Open....!!\n"); /* unsigned int n32RemainingBytes = 1920; unsigned int n32BytesRecv = 0; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0xFE); sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd<0) printf("\nSocket creation error..!!\n\n"); else printf("\nSocket Created...!!\n"); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(server_port); servaddr.sin_addr.s_addr = inet_addr(server_addr); cliaddr.sin_family = AF_INET; cliaddr.sin_port = htons(client_port); cliaddr.sin_addr.s_addr = inet_addr(client_addr); //setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,&n,sizeof(n)); //printf("Socket RECV_BUFF Set to 512X512..\n\n"); memset(&(servaddr.sin_zero),'\0',8); // Bind with Client if((bind(sockfd,(struct sockaddr *) &cliaddr,sizeof(cliaddr))<0)) { perror("bind error .. !!"); exit(0); } else printf("Socket Bind...!!\n\n"); IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0xFC); rc = listen(sockfd,5); printf("\n\t#.Listening from remote Client...!!"); s1 = accept(sockfd,NULL,NULL); printf("\n\t#. Accept The Connection...!!"); if(s1<0) { perror("accept call failed"); return; } else printf("\n\t# Connection establish...!!"); */ //----------------------------------------------------------------------------------------------------------------------------------------- printf("\n\t\t\tReady to Receive Serial data From remote Synchronous System\n"); edge_capture = 0; edge_capture2 = 0; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0xFF); while(1) { /* while(edge_capture2) //w.r.t. Start { edge_capture2 = 0; //reset generated STRT_OUT interrupt LPktCount = 0; Count = 0; do { if(edge_capture) //w.r.t. clock or LOAD Pulse from "sync_detect" { edge_capture = 0; //reset generated LOAD interrupt ImgBuff = IORD_ALTERA_AVALON_PIO_DATA(DATA_IN_BASE); Count++; if(Count == PktSize) //check end of packet-data -->640 { Count = 0; //Point to Start of packet data LPktCount++; //Increment packet Count } } }while(LPktCount != (PktCount)); */ strt_out = IORD_ALTERA_AVALON_PIO_DATA(STRT_OUT_BASE); if(strt_out ==1) //w.r.t. Start { LPktCount = 0; Count = 0; do { load = IORD_ALTERA_AVALON_PIO_DATA(LOAD_BASE); if(load == 1) //w.r.t. clock or LOAD Pulse from "sync_detect" { //edge_capture = 0; //reset generated LOAD interrupt ImgBuff = IORD_ALTERA_AVALON_PIO_DATA(DATA_IN_BASE); Count++; if(Count == PktSize) //check end of packet-data -->640 { Count = 0; //Point to Start of packet data LPktCount++; //Increment packet Count } } else { do { load = IORD_ALTERA_AVALON_PIO_DATA(LOAD_BASE); }while(load == 0); } }while(LPktCount != (PktCount)); printf("\n\t#Count = %d\t LPktCount = %d",Count,LPktCount); printf("\n\t#Synchronous Data received...!!"); usleep(1000000); printf("\n\t#Sending Data at RS232 Port at 115kbps...\n"); IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0xF0); printf("\n\t# Send Sync Word.."); for(Count = 0; Count<=2;Count++) { fprintf(fp,"%c",strt_sync); //printf("\t%d",strt_sync); } printf("\n"); Xstart = 0; Ystart = 0; LPktCount = 0; for(LPktCount = 0+Ystart; LPktCount<mPktCount;LPktCount++) { for(DataCount = 0; DataCount<mPktSize;DataCount++) { fprintf(fp,"%c",ImgBuff); } printf(">"); } LPktCount = 0; Count = 0; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0xFC); printf("\n\t#Send Done....\n\t#Ready to receive Data.\n"); } else { do { strt_out = IORD_ALTERA_AVALON_PIO_DATA(STRT_OUT_BASE); }while(strt_out == 0); } } printf("\n\t\t\tConnection Closed ..."); close(sockfd); fclose(fp); printf("\n STRT_OUT = %d\n LOAD = %d",edge_capture,edge_capture2); } //Close Simple_SOcket_Server int CheckSync(int RxSync,int IndexRxSync) { int SyncWord = {164,92,51}; int count; int MatchCount = 0; for(count = 0;count<3;count++) { if(RxSync == SyncWord) MatchCount++; IndexRxSync = (IndexRxSync + 1) % 3; } if(MatchCount == 3) return 1; else return 0; } int CheckReset(int RxResetSync,int IndexRxResetSync) { int ResetWord = {235,144,3,30}; int count; int MatchCount = 0; for(count = 0;count<4;count++) { if(RxResetSync == ResetWord) MatchCount++; IndexRxResetSync = (IndexRxResetSync + 1) % 4; } if(MatchCount == 4) return 1; else return 0; }
0 Kudos
Altera_Forum
Honored Contributor II
443 Views

How do i add a small fifo into the hardware, I do not know how do i do this --please suggest me. 

 

i have attached my "tserd_3c120_sopc.sopc", please remove .txt extension. 

 

i am still getting shifted image through my non-interrupt/interrupt version of software attached in previous post. 

 

Regards 

kkk
0 Kudos
Reply