TMCStepper
Library supporting Trinamic Stepper Drivers for Arduino platforms
Loading...
Searching...
No Matches
bcm2835_stream.cpp
Go to the documentation of this file.
1
4#ifdef bcm2835
5
6#include <cstring>
7#include <termios.h>
8#include <sys/ioctl.h>
9#include <sys/types.h>
10#include <sys/stat.h>
11#include <unistd.h>
12#include "bcm2835_stream.h"
13
14uint32_t millis()
15{
16 struct timeval now;
17 gettimeofday(&now, NULL);
18 return (uint32_t) ( now.tv_usec / 1000 );
19}
20
21Stream::Stream(const char* port)
22{
23 Stream::port = port;
24}
25
26void Stream::begin(unsigned long baud, int flags)
27{
28 termios options{};
29
30 fd = open(port, flags);
31 if (fd == -1) {
32 printf("[ERROR] UART open(%s)\n", port);
33 return;
34 }
35 fcntl(fd, F_SETFL, O_RDWR);
36
37 #if 1
38
39 speed_t myBaud;
40 switch ( baud )
41 {
42 case 9600: myBaud = B9600; break;
43 case 19200: myBaud = B19200; break;
44 case 38400: myBaud = B38400; break;
45 case 57600: myBaud = B57600; break;
46 case 115200: myBaud = B115200; break;
47 case 230400: myBaud = B230400; break;
48 case 460800: myBaud = B460800; break;
49 case 500000: myBaud = B500000; break;
50 case 576000: myBaud = B576000; break;
51
52 // The TMC2209 maxed out around 750kbaud so other enums after 576kbaud is not needed.
53
54 default:
55 printf("[ERROR] UART invalid baud: %ld for port: %s\n", baud, port);
56 return;
57 }
58
59 tcgetattr(fd, &options);
60
61 cfmakeraw( &options );
62 cfsetispeed( &options, myBaud );
63 cfsetospeed( &options, myBaud );
64
65 // See: https://www.mkssoftware.com/docs/man5/struct_termios.5.asp
66 // Use 8 data bit, no parity and 1 stop bit
67 // Set bits per byte
68 options.c_cflag |= ( CREAD | CLOCAL ) ; // turn on READ and ignore modem ctrl lines
69 // CBAUDEX no need to use extended baud; setting this for some reason shows incorrect timing on the oscilloscope for 9600 but OK for 57600
70 // Not setting it seems to be OK on the oscilloscope for both 9600 and 57600.
71 options.c_cflag &= ~PARENB; // no parity
72 options.c_cflag &= ~CSTOPB; // 1 stop bit
73 options.c_cflag &= ~CSIZE; // reset number of bits mask
74 options.c_cflag |= CS8; // 8 data bit
75 options.c_cflag &= ~CRTSCTS; // no flow control
76
77 options.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl
78 options.c_iflag |= IGNPAR; // ignore characters with parity errors
79
80 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ; // make raw
81
82 options.c_oflag &= ~OPOST; // make raw
83
84 // See: http://unixwiz.net/techtips/termios-vmin-vtime.html
85 options.c_cc[VMIN] = 0;
86 // Cannot set VTIME to 0 as it creates more problems such as cannot read the driver properly.
87 // Also, you do not want to set to 100 because it is a blocking read and timeout in VTIME and can take up to 10 seconds and
88 // if retries are implemented in caller then it feels like something is blocking for N retries x VTIME.
89 options.c_cc[ VTIME ] = 10; // VTIME defined as tenths of a second so 100 is actually 10 seconds; and 10 deciseconds is 1 second.
90
91 tcflush(fd, TCIOFLUSH); // flush both tx and rx
92
93 #else
94
95 // Use 8 data bit, no parity and 1 stop bit
96 tcgetattr(fd, &options);
97 options.c_cflag = CS8 | CLOCAL | CREAD | CBAUDEX;
98 options.c_cflag &= ~CBAUD; // use the extended baud
99 options.c_cflag &= ~PARENB; // no parity
100 options.c_cflag &= ~CSTOPB; // 1 stop bit
101 options.c_iflag = IGNPAR;
102 options.c_oflag = baud;
103 options.c_lflag = baud;
104
105 tcflush(fd, TCIFLUSH);
106
107 #endif
108
109 tcsetattr(fd, TCSANOW, &options);
110
111 // Maybe add 10ms delay (belt and braces) to let UART setup correctly
112 const int DELAY_MS_10 = 10;
113 usleep( 1000 * DELAY_MS_10 );
114}
115
116void Stream::end()
117{
118 ::close(fd);
119}
120
122{
123 int result;
124 if (ioctl(fd, FIONREAD, &result) == -1)
125 return -1;
126 return result;
127}
128
129uint8_t Stream::write(const uint8_t data)
130{
131 return (uint8_t)::write(fd, &data, 1);
132}
133
134uint8_t Stream::read()
135{
136 uint8_t data = -1;
137 if (::read(fd, &data, 1) == -1)
138 return -1;
139 return data;
140}
141
142Stream Serial("/dev/serial0");
143Stream Serial1("/dev/serial1");
144
145#endif // bcm2835
Stream Serial1
Stream Serial
uint32_t millis()
void begin(unsigned long baud)
Stream(const char *port)
void end()
uint8_t read()
int available(void)
uint8_t write(const uint8_t data)