Hello,
I am using UART 3 on imx6 and I want to know when my first byte is being sent.
At the moment, I'm polling the TXDC flag to know it but I want to do it with an interrupt.
The TCEN bit in UCR4, allows the interrupt to be asserted (interrupt_uart) but I don't know how to catch it !
I've configure many register to generate this interrupt but I don't know how to catch it ...
I you have any answers or tips to help me, it would be nice !
Thank you already ,
Florian
 
					
				
		
 igorpadykov
		
			igorpadykov
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		Hi Florian
description of interrupt configuration and some uart tests can be found in
sect.2.1.2 Interrupts (Operation), sect.4.11 Universal Asynchronous Receiver/Transmitter (UART)
attached Linux Manual, uart test :
mxc_uart_test\test - imx-test - i.MX Driver Test Application Software
Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Guys,
I tried looking the links but didn't find.
Can you please point me the UART code (Interrupt for send/receive each byte) for imx7?
 
					
				
		
 igorpadykov
		
			igorpadykov
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		Thank for your detailed reply.
I could hook-up SIGIO handler and see handler getting called when there is data on respective UART. but I have few issues:
1. SIGIO handler gets called only when bunch of bytes are available (not on each byte)
2. SIGIO getting called without missing as long as I had only UART_B, when I added UART_C also, i see inconsistency and data loss in handler.
3. I use Colibri iMX7d (emmc) evl board, I can use only 2 UART (B and C), not sure how and what to modify in device tree and rebuild bitbake to get all UART /dev/ttymx3 to 7
Pasting my code:
#define BAUDRATE B115200
#define COMM_PORT_B "/dev/ttymxc1"
#define COMM_PORT_C "/dev/ttymxc1"
#define COMM_PORT_D "/dev/ttymxc1"
#define NO_OF_UART 2
static int fd[NO_OF_UART] = {0}; 
static int max_fds = 0;
static fd_set read_fd;
static char comm_port[NO_OF_UART][16] = {
 {COMM_PORT_B},
 {COMM_PORT_C},
// {COMM_PORT_D},
};
static uint8_t uart_buf[UART_DATA_LEN];
volatile uint8_t uart_flag;
static void UART_INT (int sig)
{
 char rx_buf[UART_DATA_LEN] = {'\0'};
 int res = 0;
 int i = 0;
for(i = 0; i < NO_OF_UART; i++) 
 { 
 if(FD_ISSET(fd[i], &read_fd)) {
 res = read(fd[i], &rx_buf, UART_DATA_LEN);
 if(res > 0) {
 //data received, copy into buffer with flag and clear the buffer
 uart_flag |= (1<<i); //set respective flag
 memcpy(uart_buf, rx_buf, res);
 memset(rx_buf, '\0', UART_DATA_LEN);
 }
 }
 }
}
int init_uart(int *fd, const char *port)
{
 int rc = 0;
 char cmd[CMD_STR_LEN] = {'\0'};
 struct termios newtio;
 struct sigaction saio;
sprintf(cmd, "stty -F %s 115200 -echo", port); 
 system(cmd);
memset(cmd, '\0', CMD_STR_LEN);
 sprintf(cmd, "cat < %s &", port);
 system(cmd);
 
 *fd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
 if(*fd < 0) {
 perror(port); 
 exit(-1);
 }
saio.sa_handler = UART_INT;
 sigemptyset(&saio.sa_mask);
 saio.sa_flags = SA_SIGINFO;
 sigaction(SIGIO, &saio,NULL);
 
 fcntl (*fd, F_SETOWN, getgid());
 fcntl(*fd, F_SETFL, FASYNC);
 
 newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD ;
 newtio.c_iflag = IGNPAR | IXOFF;
 newtio.c_oflag = 0;
 newtio.c_lflag = 0;
 newtio.c_cc[VMIN] = 0;
 newtio.c_cc[VTIME] = 0;
 tcflush(*fd, TCIFLUSH);
 tcsetattr(*fd, TCSANOW, &newtio);
return rc;
}
static uint8_t cal_crc(uint8_t *byte, size_t len)
{
 uint8_t crc = 0xFF;
 size_t i, j;
for(i = 0; i < len; i++) 
 {
 crc ^= byte[i];
 for(j = 0; j < 8; j++)
 {
 if((crc & 0x80) != 0) {
 crc = (uint8_t) ((crc << 1) ^ 0x31);
 } else {
 crc <<= 1;
 }
 }
 }
 return crc;
}
int send_data(int fd, uint8_t *buf)
{
 int rc = 0;
 int size = buf[NO_OF_BYTES] + 2;
 buf[size] = cal_crc(buf,buf[NO_OF_BYTES] + 1); 
 rc = write(fd, (char *)buf, size); 
 
 return rc;
}
// Keep reentrant as this function runs in serveral instances 
static int uart_trigger(void *index)
{
 int rc = 0;
 do
 {
 FD_SET(fd[*(int *)index], &read_fd);
 pselect(max_fds + 1, &read_fd, NULL, NULL, NULL, NULL);
}while(1);
return rc;
}
static int largest_num(int arr[], int n)
{
 int i;
 int max = arr[0];
 
 for(i = 1; i < n; i++)
 {
 if(arr[i] > max) {
 max = arr[i];
 }
 }
 return max;
}
int uart_main(void *td)
{ 
 int rc = 0;
 int mydata = *(int *)td;
 int i = 0;
 pthread_t thread_id[NO_OF_UART];
 int tr = 0;
 int arg[NO_OF_UART] = {0};
 
 printf("%s() called thread ID: %d\n", __FUNCTION__, mydata);
for(i = 0; i < NO_OF_UART; i++) {
 init_uart(&fd[i], comm_port[i]);
 }
//calculate max fds
 max_fds = largest_num(fd, NO_OF_UART);
FD_ZERO(&read_fd);
for(i = 0; i < NO_OF_UART; i++) {
 arg[i] = i;
 rc |= pthread_create(&(thread_id[i]), NULL, (void *) uart_trigger, (void *)&arg[i]);
}
 do {
 switch(uart_flag)
 {
 case UART_B_DATA:
 printf("UART_B: %s\n", uart_buf);
 memset(uart_buf, '\0', UART_DATA_LEN);
 uart_flag &= ~UART_B_DATA;
break;
 case UART_C_DATA:
 printf("UART_C: %s\n", uart_buf);
 memset(uart_buf, '\0', UART_DATA_LEN);
 uart_flag &= ~UART_C_DATA;
break;
 }
}while(1);
 for(i = 0; i < NO_OF_UART; i++) {
 rc |=pthread_join(thread_id[i], (void **)&tr);
 printf("Thread: %d %s\n", i, tr==0?"SUCCESS":"FAILED");
 }
 return rc; 
}
Please suggest me on this....
