102 lines
2.7 KiB
C
102 lines
2.7 KiB
C
// serial_to_stdout.c
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <termios.h>
|
|
#include <errno.h>
|
|
|
|
#define DEFAULT_PORT "/dev/ttyESP32_A"
|
|
#define DEFAULT_BAUD B1500000
|
|
#define BLOCK_SIZE 512 // PCM bytes per block
|
|
#define MAGIC 0xABCD // header marker
|
|
|
|
int open_serial(const char *path, speed_t baud) {
|
|
int fd = open(path, O_RDONLY | O_NOCTTY);
|
|
if (fd < 0) { perror("open"); return -1; }
|
|
|
|
struct termios tio;
|
|
if (tcgetattr(fd, &tio) != 0) { perror("tcgetattr"); close(fd); return -1; }
|
|
|
|
cfsetispeed(&tio, baud);
|
|
cfsetospeed(&tio, baud);
|
|
|
|
// Raw mode
|
|
tio.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | INLCR | IXON | IXOFF | IXANY |
|
|
PARMRK | INPCK | ISTRIP);
|
|
tio.c_oflag &= ~(OPOST);
|
|
tio.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
|
|
tio.c_cflag &= ~(CSIZE | PARENB | CSTOPB | CRTSCTS);
|
|
tio.c_cflag |= (CS8 | CLOCAL | CREAD);
|
|
|
|
tio.c_cc[VMIN] = 1;
|
|
tio.c_cc[VTIME] = 0;
|
|
|
|
if (tcsetattr(fd, TCSANOW, &tio) != 0) { perror("tcsetattr"); close(fd); return -1; }
|
|
|
|
return fd;
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
const char *port = (argc > 1) ? argv[1] : DEFAULT_PORT;
|
|
speed_t baud = DEFAULT_BAUD;
|
|
|
|
int fd = -1;
|
|
|
|
while (1) {
|
|
if (fd < 0) {
|
|
// Try to open serial port
|
|
fd = open_serial(port, baud);
|
|
if (fd < 0) {
|
|
fprintf(stderr, "Waiting for device %s...\n", port);
|
|
sleep(2);
|
|
continue;
|
|
}
|
|
fprintf(stderr, "Connected to %s\n", port);
|
|
}
|
|
|
|
// Read header
|
|
uint8_t hbuf[2];
|
|
ssize_t hn = read(fd, hbuf, 2);
|
|
if (hn != 2) {
|
|
// Error or disconnect
|
|
if (hn == 0 || (hn < 0 && errno != EINTR)) {
|
|
fprintf(stderr, "Device disconnected, retrying...\n");
|
|
close(fd);
|
|
fd = -1;
|
|
sleep(2);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
uint16_t hdr = hbuf[0] | (hbuf[1] << 8);
|
|
if (hdr != MAGIC) {
|
|
// Not aligned, skip
|
|
continue;
|
|
}
|
|
|
|
// Accumulate one full PCM block
|
|
uint8_t block[BLOCK_SIZE];
|
|
size_t got = 0;
|
|
while (got < BLOCK_SIZE) {
|
|
ssize_t m = read(fd, block + got, BLOCK_SIZE - got);
|
|
if (m <= 0) {
|
|
// Disconnect mid-block
|
|
fprintf(stderr, "Read error/disconnect mid-block, retrying...\n");
|
|
close(fd);
|
|
fd = -1;
|
|
break;
|
|
}
|
|
got += (size_t)m;
|
|
}
|
|
|
|
if (fd >= 0 && got == BLOCK_SIZE) {
|
|
fwrite(block, 1, BLOCK_SIZE, stdout);
|
|
fflush(stdout);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|