Last active
February 17, 2024 22:53
-
-
Save ultramcu/cbdc598bbc1fcd0e5f8a to your computer and use it in GitHub Desktop.
C Library for Raspberry Pi Send/Receive Serial
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/************************* | |
* UART For Raspberry Pi (2014/10/10) | |
* gcc version 4.6.3 (Debian 4.6.3-14+rpi1) | |
* | |
* copyright ultra_mcu@msn.com | |
* www.appstack.in.th | |
* https://github.com/ultramcu/AppStackUART | |
* ***********************/ | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <termios.h> | |
#include <stdlib.h> | |
#include <pthread.h> | |
#include <stdint.h> | |
#include <sys/select.h> | |
#include <string.h> | |
#include <time.h> | |
#include <glob.h> | |
#include <netinet/in.h> | |
#include <sys/socket.h> | |
#include <sys/types.h> | |
#include "app_stack_uart.h" | |
int32_t uart_begin(st_uart *s_uart,char *device,int32_t baudrate,int32_t (*callback)(void *)) | |
{ | |
struct termios termOptions; | |
struct termios options; | |
int32_t br = 0; | |
if(callback != NULL) | |
{ | |
s_uart->callback_function = callback; | |
} | |
if(baudrate >= 1200 && baudrate <= 230400) | |
{ | |
br = convert_baudrate(baudrate); | |
} | |
else | |
{ | |
printf ("Error : baudrate must be 1200 - 230400\r\n"); | |
return _FALSE_; | |
} | |
s_uart->serial_fd = -1; | |
s_uart->serial_fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); | |
if (s_uart->serial_fd == -1) | |
{ | |
printf ("Error : open serial device: %s\r\n",device); | |
perror("OPEN"); | |
return _FALSE_; | |
} | |
tcgetattr(s_uart->serial_fd, &options); | |
options.c_cflag = br | CS8 | CLOCAL | CREAD; //<Set baud rate | |
options.c_iflag = IGNPAR; | |
options.c_oflag = 0; | |
options.c_lflag = 0; | |
tcflush(s_uart->serial_fd, TCIFLUSH); | |
if( tcsetattr(s_uart->serial_fd, TCSANOW, &options) < 0) | |
{ | |
printf("ERROR : Setup serial failed\r\n"); | |
return _FALSE_; | |
} | |
if (pthread_create(&s_uart->th_recv, NULL, (void *)th_serial_recv, (void *)(s_uart)) != _TRUE_) | |
{ | |
printf("ERROR : initial thread receive serial failed\r\n"); | |
return _FALSE_; | |
} | |
return _TRUE_; | |
} | |
int32_t serial_send(st_uart *s_uart,char *data) | |
{ | |
if(strlen(data) < _UART_BUFFER_SIZE_) | |
{ | |
memset(s_uart->send_buff,0,sizeof(s_uart->send_buff)); | |
sprintf(s_uart->send_buff,"<%s>",data); | |
return write(s_uart->serial_fd, s_uart->send_buff, strlen(s_uart->send_buff)); | |
} | |
return -1; | |
} | |
int32_t th_serial_recv(void *arg) | |
{ | |
st_uart *s_uart = (st_uart *)arg; | |
fd_set rset; | |
struct timeval tv; | |
int32_t count = 0; | |
uint8_t state = 0; | |
uint8_t i = 0; | |
while(1) | |
{ | |
FD_ZERO(&rset); | |
FD_SET(s_uart->serial_fd, &rset); | |
tv.tv_sec = 30; | |
tv.tv_usec = 0; | |
count = select(s_uart->serial_fd + 1, &rset, NULL, NULL, &tv); | |
if(count > 0) | |
{ | |
memset(s_uart->recv_temp,0,_UART_BUFFER_SIZE_); | |
s_uart->recv_temp_cnt = read(s_uart->serial_fd, (void*)s_uart->recv_temp, _UART_BUFFER_SIZE_); | |
for(i = 0; i < s_uart->recv_temp_cnt; i++) | |
{ | |
switch(state) | |
{ | |
case 0: //check header < | |
if(s_uart->recv_temp[i] == _UART_PROTO_HEADER_) | |
{ | |
state = 1; | |
s_uart->recv_buff_cnt = 0; | |
} | |
break; | |
case 1: //copy data to buffer | |
if(s_uart->recv_temp[i] == _UART_PROTO_HEADER_) | |
{ | |
s_uart->recv_buff_cnt = 0; | |
} | |
else if(s_uart->recv_temp[i] == _UART_PROTO_FOOTER_) | |
{ | |
memset(s_uart->data.data,0,_UART_BUFFER_SIZE_); | |
memcpy(s_uart->data.data,s_uart->recv_buff,s_uart->recv_buff_cnt); | |
s_uart->data.count = s_uart->recv_buff_cnt; | |
state = 0; | |
memset(s_uart->recv_buff,0,_UART_BUFFER_SIZE_); | |
if(s_uart->callback_function != NULL) | |
{ | |
(*s_uart->callback_function)(&s_uart->data); | |
} | |
} | |
else | |
{ | |
s_uart->recv_buff[s_uart->recv_buff_cnt++] = s_uart->recv_temp[i]; | |
} | |
break; | |
} | |
//printf("Out State = %d, char = %c\r\n",state,s_uart->recv_temp[i]); | |
} | |
} | |
else | |
{ | |
if(s_uart->serial_fd < 0) | |
{ | |
//close serial | |
close(s_uart->serial_fd); | |
} | |
} | |
} | |
} | |
int32_t convert_baudrate(int32_t baudrate) | |
{ | |
switch(baudrate) | |
{ | |
case 1200: return B1200; | |
case 2400: return B2400; | |
case 4800: return B4800; | |
case 9600: return B9600; | |
case 19200: return B19200; | |
case 38400: return B38400; | |
case 57600: return B57600; | |
case 115200: return B115200; | |
case 230400: return B230400; | |
} | |
return B9600; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/************************* | |
* UART For Raspberry Pi (2014/10/10) | |
* gcc version 4.6.3 (Debian 4.6.3-14+rpi1) | |
* | |
* copyright ultra_mcu@msn.com | |
* www.appstack.in.th | |
* https://github.com/ultramcu/AppStackUART | |
* ***********************/ | |
#ifndef APP_STACK_UART_H | |
#define APP_STACK_UART_H | |
#include <pthread.h> | |
#include <stdint.h> | |
#define _UART_BUFFER_SIZE_ 255 | |
#define _UART_PROTO_HEADER_ '<' | |
#define _UART_PROTO_FOOTER_ '>' | |
#define _TRUE_ 0 | |
#define _FALSE_ -1 | |
typedef struct | |
{ | |
uint32_t count; | |
char data[_UART_BUFFER_SIZE_]; | |
}st_uart_data; | |
typedef struct | |
{ | |
uint32_t serial_fd; | |
pthread_t th_recv; | |
int32_t recv_temp_cnt; | |
int32_t recv_buff_cnt; | |
char recv_temp[_UART_BUFFER_SIZE_]; | |
char recv_buff[_UART_BUFFER_SIZE_]; | |
char send_buff[_UART_BUFFER_SIZE_ + 2]; | |
int32_t (*callback_function)(void *); | |
st_uart_data data; | |
}st_uart; | |
int32_t serial_send(st_uart *s_uart,char *data); | |
int32_t uart_begin(st_uart *s_uart,char *device,int32_t baudrate,int32_t (*callback)(void *)); | |
int32_t convert_baudrate(int32_t baudrate); | |
int32_t th_serial_recv(void *arg); | |
#endif // APP_STACK_UART_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/************************* | |
* UART For Raspberry Pi (2014/10/10) | |
* gcc version 4.6.3 (Debian 4.6.3-14+rpi1) | |
* | |
* copyright ultra_mcu@msn.com | |
* www.appstack.in.th | |
* https://github.com/ultramcu/AppStackUART | |
* ***********************/ | |
#include <stdint.h> | |
#include <stdio.h> | |
#include "app_stack_uart.h" | |
#define _SERIAL_DEV_ "/dev/ttyACM0" | |
st_uart MY_UART; | |
int32_t my_uart_callback_function(void *arg) | |
{ | |
st_uart_data *data = (st_uart_data *)arg; | |
printf("Received %2d Bye, Data : %s\r\n",data->count,data->data); | |
} | |
int main(void) | |
{ | |
system("clear"); | |
printf("********************************\r\n"); | |
printf("* Raspberry Pi UART library *\r\n"); | |
printf("* *\r\n"); | |
printf("* www.appstack.in.th *\r\n"); | |
printf("* (2014/10/10) *\r\n"); | |
printf("********************************\r\n"); | |
printf("\r\n"); | |
if(uart_begin(&MY_UART,_SERIAL_DEV_,9600,&my_uart_callback_function) != _TRUE_) | |
{ | |
printf("Error : uart_begin failed\r\n"); | |
return 0; | |
} | |
while(1) | |
{ | |
serial_send(&MY_UART,"Hello send from Raspberry Pi."); | |
serial_send(&MY_UART,"A"); | |
sleep(1); | |
serial_send(&MY_UART,"www.appstack.in.th"); | |
serial_send(&MY_UART,"B"); | |
sleep(1); | |
} | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment