I have given up on trying to solve this.
I can't find anything wrong with what I am doing but the Pi keeps outputting only 16 bytes
although it reports it writes all of them. (it prints a=64 but only 16 bytes go out)
I even went in the minicom source code to see what they do
(as it works for them) but their open and init code gives me the same result.
I'll use my workaround which uses a usleep and is good enough for my application.
I can't spend anymore time on this
Code below: write_uart1 fails, write_uart2 is my workaround and is fine.
Code: Select all
//
// Raspberry-Pi UART access from C
//
// Code based on
// http://www.raspberrypi.org/phpBB3/viewtopic.php?t=7500&p=93257
// mixed with minicom code
//
#include <unistd.h> //Used for UART
#include <fcntl.h> //Used for UART
#include <termios.h> //Used for UART
int open_uart(int low);
int write_uart1(void *data,int bytes);
int write_uart2(void *data,int bytes);
void close_uart();
// debug:
#include <stdio.h>
char pattern[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz\015\012";
// test
int main()
{
if (open_uart(0)!=0)
{ fprintf(stderr,"Could not open UART\n");
return 1;
}
while (1)
{
write_uart2(pattern,64);
sleep(2);
}
return 0;
} // main
int uart0_filestream = -1;
//
// Setup Raspberry-Pi UART
// return 0 on success
// return 1 on failure
//
// Code based on http://www.raspberrypi.org/phpBB3/viewtopic.php?t=7500&p=93257
//
int open_uart(int low)
{ int n;
struct termios options;
if (uart0_filestream!=-1)
return 0; // assume already opened
uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY); //Open in non blocking read/write mode
if (uart0_filestream == -1)
{
fprintf(stderr,"Error - Unable to open UART. Ensure it is not in use by another application\n");
fflush(stderr);
return 1;
}
// cancel the O_NDELAY flag
// (copied from minicom)
n = fcntl(uart0_filestream, F_GETFL, 0);
fcntl(uart0_filestream, F_SETFL, n & ~O_NDELAY);
// CONFIGURE THE UART
// The flags (defined in /usr/include/termios.h -
// see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html):
tcgetattr(uart0_filestream, &options);
cfsetospeed(&options,B57600);
cfsetispeed(&options,B57600);
options.c_cflag = (options.c_cflag & ~CSIZE) | CS8; // 8 bits
options.c_cflag |= CLOCAL | CREAD; // ignore mode status, enable rec.
options.c_cflag &= ~(PARENB | PARODD | CSTOPB); // No parity, 1 stop bit
options.c_iflag = IGNBRK;
options.c_iflag &= ~(IXON|IXOFF|IXANY);
options.c_oflag = 0;
options.c_lflag = 0;
tcsetattr(uart0_filestream, TCSANOW, &options); // set the options NOW
return 0;
} // setup_uart
// what it says
void close_uart()
{
if (uart0_filestream!=-1)
close(uart0_filestream);
}
//
// transmit data to uart
// This is how it should work
//
// return 0 on failure
// return 1 on success
//
int write_uart1(void *data,int bytes)
{ int a;
while (bytes)
{
a = write(uart0_filestream, data, bytes);
if (a==-1)
{ fprintf(stderr,"UART WRITE ERRROR!!\n");
return 0;
}
bytes -= a;
printf("a=%d\n",a);
data = (void *)((char *)data + a);
}
tcflush(uart0_filestream,TCOFLUSH);
return 1;
} // tx_uart
//
// transmit data to uart
// max 16 at a time
// wait for 16 charac to leave before pushing more out
//
// return 0 on failure
// return 1 on success
//
int write_uart2(void *data,int bytes)
{ int b,a;
while (bytes)
{
b = bytes>=16 ? 16 : bytes;
a = write(uart0_filestream, data, b);
if (a==-1)
{ fprintf(stderr,"UART WRITE ERRROR!!\n");
return 0;
}
bytes -= a;
printf("a=%d\n",a);
data = (void *)((char *)data + a);
usleep(30000); // > 16charsx10bits/57600
}
tcflush(uart0_filestream,TCOFLUSH);
return 1;
} // tx_uart