/** * Read data from SPI bus. * Since we are master, we have to trigger slave by sending * fake chars on the bus. */ static size_t spimaster_read(struct KFile *fd, void *_buf, size_t size) { Serial *fd_spi = SERIAL_CAST(fd); ser_flush(&fd_spi->fd); ser_purgeRx(fd_spi); size_t total_rd = 0; uint8_t *buf = (uint8_t *)_buf; int c; while (size--) { /* * Send and receive chars 1 by 1, otherwise the rxfifo * will overrun. */ ser_putchar(0, fd_spi); if ((c = ser_getchar(fd_spi)) == EOF) break; *buf++ = c; total_rd++; } return total_rd; }
int ser_open (int *serRef, struct termios *oldtio, char *deviceName, long baudRate) { int status = 0; struct termios newtio; /*open the device to be non-blocking*/ *serRef = open(deviceName, O_RDWR | O_NOCTTY | O_NONBLOCK); if (*serRef >= 0) { /* save current port settings*/ if (oldtio != NULL) tcgetattr(*serRef, oldtio); /* set new port settings*/ /* BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed. CRTSCTS : output hardware flow control (only used if the cable has all necessary lines. See sect. 7 of Serial-HOWTO) CS8 : 8n1 (8bit,no parity,1 stopbit) CLOCAL : local connection, no modem contol CREAD : enable receiving characters CSTOPB : stop bit PARENB : parity bit */ newtio.c_cflag = CS8 | CLOCAL | CREAD; #ifdef MACOSX_USBSERIAL newtio.c_cflag = |= CSIZE; #endif cfsetspeed(&newtio, baudRate); /* must be called after setting newtio.c_flag */ newtio.c_iflag = IGNPAR; newtio.c_oflag = 0; newtio.c_lflag = 0; newtio.c_cc[VMIN]=0; /* non-blocking read*/ newtio.c_cc[VTIME]=0; ser_flush (*serRef); tcsetattr(*serRef,TCSANOW,&newtio); } else
/** * Clean up serial port, disabling the associated hardware. */ static int ser_close(struct KFile *fd) { Serial *fds = SERIAL_CAST(fd); Serial *port = fds; ASSERT(port->is_open); DB(port->is_open = false); // Wait until we finish sending everything ser_flush(fd); port->hw->table->cleanup(port->hw); DB(port->hw = NULL); /* * We purge the FIFO buffer only after the low-level cleanup, so that * we are sure that there are no more interrupts. */ ser_purge(fds); return 0; }