41 #include <sys/types.h>
45 #ifdef PIOS_INCLUDE_SERIAL
47 #include <linux/serial.h>
48 #include <sys/ioctl.h>
52 #ifdef PIOS_INCLUDE_SERIAL
56 static void PIOS_SERIAL_ChangeBaud(uintptr_t serial_id, uint32_t baud);
81 #if defined(PIOS_INCLUDE_SERIAL)
99 bool rx_need_yield =
false;
102 len, NULL, &rx_need_yield);
115 const int INCOMING_BUFFER_SIZE = 16;
116 uint8_t incoming_buffer[INCOMING_BUFFER_SIZE];
119 int result = read(ser_dev->
readfd, incoming_buffer,
120 INCOMING_BUFFER_SIZE);
123 rx_do_cb(ser_dev, incoming_buffer, result);
152 int writefd,
bool dont_touch_line)
156 memset(ser_dev, 0,
sizeof(*ser_dev));
170 printf(
"serial dev %p - fd %i/%i opened\n", ser_dev,
173 *serial_id = (uintptr_t) ser_dev;
175 #if defined(PIOS_INCLUDE_SERIAL)
176 PIOS_SERIAL_ChangeBaud(*serial_id, 9600);
184 #if defined(PIOS_INCLUDE_SERIAL)
185 int fd = open(path, O_RDWR | O_NOCTTY);
188 perror(
"serial-open");
200 printf(
"serial dev %p - (path %s)\n", (
void *) (*serial_id), path);
209 #if defined(PIOS_INCLUDE_SERIAL)
210 void PIOS_SERIAL_ChangeBaud(uintptr_t serial_id, uint32_t baud)
224 struct termios options;
226 memset(&options, 0,
sizeof(options));
228 options.c_cflag = CLOCAL | CREAD | CS8;
232 printf(
"Setting Serial ID %p to 1200 bps\n",
234 cfsetispeed(&options, B1200);
235 cfsetospeed(&options, B1200);
238 printf(
"Setting Serial ID %p to 2400 bps\n",
240 cfsetispeed(&options, B2400);
241 cfsetospeed(&options, B2400);
244 printf(
"Setting Serial ID %p to 4800 bps\n",
246 cfsetispeed(&options, B4800);
247 cfsetospeed(&options, B4800);
250 printf(
"Setting Serial ID %p to 9600 bps\n",
252 cfsetispeed(&options, B9600);
253 cfsetospeed(&options, B9600);
256 printf(
"Setting Serial ID %p to 19200 bps\n",
258 cfsetispeed(&options, B19200);
259 cfsetospeed(&options, B19200);
262 printf(
"Setting Serial ID %p to 57600 bps\n",
264 cfsetispeed(&options, B57600);
265 cfsetospeed(&options, B57600);
268 printf(
"Setting Serial ID %p to 115200 bps\n",
270 cfsetispeed(&options, B115200);
271 cfsetospeed(&options, B115200);
274 printf(
"Setting Serial ID %p to 230400 bps\n",
276 cfsetispeed(&options, B230400);
277 cfsetospeed(&options, B230400);
299 struct serial_struct serinfo;
301 if (ioctl(ser_dev->
readfd, TIOCGSERIAL, &serinfo)) {
302 perror(
"ioctl-TIOCGSERIAL");
306 (serinfo.flags & ~ASYNC_SPD_MASK) |
308 serinfo.custom_divisor = (serinfo.baud_base + (baud / 2)) / baud;
309 uint32_t closest_speed = serinfo.baud_base / serinfo.custom_divisor;
311 if ((closest_speed < baud * 99 / 100) ||
312 (closest_speed > baud * 101 / 100)) {
313 printf(
"Can't attain serial rate %d; using %d\n",
314 baud, closest_speed);
317 if (ioctl(ser_dev->
readfd, TIOCSSERIAL, &serinfo)) {
318 perror(
"ioctl-TIOCSSERIAL");
322 printf(
"Setting Serial ID %p to %d bps\n",
324 cfsetispeed(&options, B38400);
325 cfsetospeed(&options, B38400);
332 options.c_cc[VMIN] = 1;
334 if (tcsetattr(ser_dev->
readfd, TCSANOW, &options)) {
356 while (tx_bytes_avail > 0) {
357 bool tx_need_yield =
false;
static pios_ser_dev * find_ser_dev_by_id(uintptr_t serial)
static void PIOS_SERIAL_RegisterRxCallback(uintptr_t udp_id, pios_com_callback rx_in_cb, uintptr_t context)
pios_com_callback rx_in_cb
const struct pios_com_driver pios_serial_com_driver
Main PiOS header to include all the compiled in PiOS options.
static void PIOS_SERIAL_TxStart(uintptr_t udp_id, uint16_t tx_bytes_avail)
#define PIOS_SERIAL_RX_BUFFER_SIZE
void * PIOS_malloc(size_t size)
static void PIOS_SERIAL_RegisterTxCallback(uintptr_t udp_id, pios_com_callback tx_out_cb, uintptr_t context)
static void PIOS_SERIAL_RxStart(uintptr_t udp_id, uint16_t rx_bytes_avail)
#define PIOS_THREAD_STACK_SIZE_MIN
static void PIOS_SERIAL_RxTask(void *ser_dev_n)
bool ever_used_custom_rate
struct pios_thread * PIOS_Thread_Create(void(*fp)(void *), const char *namep, size_t stack_bytes, void *argp, enum pios_thread_prio_e prio)
SERIAL private definitions.
int32_t PIOS_SERIAL_InitFromFd(uintptr_t *serial_id, int readfd, int writefd, bool dont_touch_line)
static void rx_do_cb(pios_ser_dev *ser_dev, uint8_t *incoming_buffer, int len)
void PIOS_Thread_Sleep(uint32_t time_ms)
int printf(const char *format,...)
pios_com_callback tx_out_cb
uint8_t tx_buffer[PIOS_SERIAL_RX_BUFFER_SIZE]
#define PIOS_Assert(test)
int32_t PIOS_SERIAL_Init(uintptr_t *serial_id, const char *path)
uint16_t(* pios_com_callback)(uintptr_t context, uint8_t *buf, uint16_t buf_len, uint16_t *headroom, bool *task_woken)
void(* set_baud)(uintptr_t id, uint32_t baud)