forked from ROMEO/obsw
uart1 IO
This commit is contained in:
parent
8e7424bb2f
commit
5ad8853fef
@ -27,6 +27,7 @@ int hw_device_open(const char *path, size_t path_len) {
|
|||||||
return UART_0;
|
return UART_0;
|
||||||
}
|
}
|
||||||
if (compare_string_chars("uart1", path, path_len) == 1) {
|
if (compare_string_chars("uart1", path, path_len) == 1) {
|
||||||
|
uart1_enable_receiver();
|
||||||
return UART_1;
|
return UART_1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ int hw_interface_read(int fd, char *ptr, int len) {
|
|||||||
case UART_0:
|
case UART_0:
|
||||||
return uart0_read(ptr,len);
|
return uart0_read(ptr,len);
|
||||||
case UART_1:
|
case UART_1:
|
||||||
return 0;
|
return uart1_read(ptr,len);;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
@ -6,6 +6,9 @@
|
|||||||
#include <xscugic.h>
|
#include <xscugic.h>
|
||||||
#include <xuartps.h>
|
#include <xuartps.h>
|
||||||
|
|
||||||
|
// TODO deduplicate calls
|
||||||
|
// TODO add semaphore to make QueueSets smaller
|
||||||
|
|
||||||
#undef XUARTPS_IXR_RXOVR
|
#undef XUARTPS_IXR_RXOVR
|
||||||
#define XUARTPS_IXR_RXOVR 0x00000020U /**< Rx Overrun error interrupt */
|
#define XUARTPS_IXR_RXOVR 0x00000020U /**< Rx Overrun error interrupt */
|
||||||
#define XUARTPS_IXR_RTRIG 0x00000001U /**< RX FIFO trigger interrupt. */
|
#define XUARTPS_IXR_RTRIG 0x00000001U /**< RX FIFO trigger interrupt. */
|
||||||
@ -16,6 +19,10 @@ uint8_t uart0_receive_buffer[1024 * 1];
|
|||||||
StaticQueue_t uart0_static_queue;
|
StaticQueue_t uart0_static_queue;
|
||||||
QueueHandle_t uart0_receive_queue;
|
QueueHandle_t uart0_receive_queue;
|
||||||
|
|
||||||
|
uint8_t uart1_receive_buffer[1024 * 1];
|
||||||
|
StaticQueue_t uart1_static_queue;
|
||||||
|
QueueHandle_t uart1_receive_queue;
|
||||||
|
|
||||||
/** this is based on XUartPs_InterruptHandler() in xuartps_intr.c*/
|
/** this is based on XUartPs_InterruptHandler() in xuartps_intr.c*/
|
||||||
void uart0_handle_interrupt(void *) {
|
void uart0_handle_interrupt(void *) {
|
||||||
u32 IsrStatus;
|
u32 IsrStatus;
|
||||||
@ -33,19 +40,55 @@ void uart0_handle_interrupt(void *) {
|
|||||||
// available into the stack
|
// available into the stack
|
||||||
uint8_t RecievedByte;
|
uint8_t RecievedByte;
|
||||||
BaseType_t xHigherPriorityTaskWoken;
|
BaseType_t xHigherPriorityTaskWoken;
|
||||||
while (XUartPs_IsReceiveData(STDIN_BASEADDRESS)) {
|
while (XUartPs_IsReceiveData(XPS_UART0_BASEADDR)) {
|
||||||
RecievedByte = XUartPs_ReadReg(STDIN_BASEADDRESS, XUARTPS_FIFO_OFFSET);
|
RecievedByte = XUartPs_ReadReg(XPS_UART0_BASEADDR, XUARTPS_FIFO_OFFSET);
|
||||||
xQueueSendToBackFromISR(uart0_receive_queue, &RecievedByte,
|
xQueueSendToBackFromISR(uart0_receive_queue, &RecievedByte,
|
||||||
&xHigherPriorityTaskWoken);
|
&xHigherPriorityTaskWoken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the interrupt status. */
|
/* Clear the interrupt status. */
|
||||||
XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_ISR_OFFSET, IsrStatus);
|
XUartPs_WriteReg(XPS_UART0_BASEADDR, XUARTPS_ISR_OFFSET, IsrStatus);
|
||||||
|
|
||||||
/* directly yield if sending to the queue woke something in ourselves */
|
/* directly yield if sending to the queue woke something in ourselves */
|
||||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uart1_handle_interrupt(void *) {
|
||||||
|
outbyte('R');
|
||||||
|
u32 IsrStatus;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the interrupt ID register to determine which
|
||||||
|
* interrupt is active
|
||||||
|
*/
|
||||||
|
IsrStatus = XUartPs_ReadReg(XPS_UART1_BASEADDR, XUARTPS_IMR_OFFSET);
|
||||||
|
|
||||||
|
IsrStatus &= XUartPs_ReadReg(XPS_UART1_BASEADDR, XUARTPS_ISR_OFFSET);
|
||||||
|
|
||||||
|
// Onlx RX intterupts are enabled
|
||||||
|
// We do not care which interrupt actually triggered, just get all bytes
|
||||||
|
// available into the stack
|
||||||
|
uint8_t RecievedByte;
|
||||||
|
BaseType_t xHigherPriorityTaskWoken;
|
||||||
|
|
||||||
|
while (XUartPs_IsReceiveData(XPS_UART1_BASEADDR)) {
|
||||||
|
RecievedByte = XUartPs_ReadReg(XPS_UART1_BASEADDR, XUARTPS_FIFO_OFFSET);
|
||||||
|
outbyte(RecievedByte);
|
||||||
|
outbyte(XUartPs_ReadReg(XPS_UART1_BASEADDR, XUARTPS_ISR_OFFSET));
|
||||||
|
xQueueSendToBackFromISR(uart1_receive_queue, &RecievedByte,
|
||||||
|
&xHigherPriorityTaskWoken);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Clear the interrupt status. */
|
||||||
|
XUartPs_WriteReg(XPS_UART1_BASEADDR, XUARTPS_ISR_OFFSET, IsrStatus);
|
||||||
|
|
||||||
|
outbyte('X');
|
||||||
|
outbyte('\n');
|
||||||
|
/* directly yield if sending to the queue woke something in ourselves */
|
||||||
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||||
|
}
|
||||||
|
|
||||||
void uart0_enable_receiver() {
|
void uart0_enable_receiver() {
|
||||||
uart0_receive_queue =
|
uart0_receive_queue =
|
||||||
xQueueCreateStatic(sizeof(uart0_receive_buffer), 1, uart0_receive_buffer,
|
xQueueCreateStatic(sizeof(uart0_receive_buffer), 1, uart0_receive_buffer,
|
||||||
@ -76,6 +119,36 @@ void uart0_enable_receiver() {
|
|||||||
XScuGic_Enable(&xInterruptController, XPAR_XUARTPS_0_INTR);
|
XScuGic_Enable(&xInterruptController, XPAR_XUARTPS_0_INTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uart1_enable_receiver() {
|
||||||
|
uart1_receive_queue =
|
||||||
|
xQueueCreateStatic(sizeof(uart1_receive_buffer), 1, uart1_receive_buffer,
|
||||||
|
&uart1_static_queue);
|
||||||
|
|
||||||
|
/* Install the UART Interrupt handler. */
|
||||||
|
BaseType_t xStatus =
|
||||||
|
XScuGic_Connect(&xInterruptController, XPAR_XUARTPS_1_INTR,
|
||||||
|
(Xil_ExceptionHandler)uart1_handle_interrupt, NULL);
|
||||||
|
configASSERT(xStatus == XST_SUCCESS);
|
||||||
|
(void)xStatus; /* Remove compiler warning if configASSERT() is not defined. */
|
||||||
|
|
||||||
|
// Set trigger level to 62 of 64 bytes, giving interrupt some time to react
|
||||||
|
XUartPs_WriteReg(XPS_UART1_BASEADDR, XUARTPS_RXWM_OFFSET, 62);
|
||||||
|
|
||||||
|
// Setting the rx timeout to n*4 -1 bits
|
||||||
|
XUartPs_WriteReg(XPS_UART1_BASEADDR, XUARTPS_RXTOUT_OFFSET, 50);
|
||||||
|
|
||||||
|
// enable UART Interrupts
|
||||||
|
u32 mask = XUARTPS_IXR_RTRIG | XUARTPS_IXR_RXOVR | XUARTPS_IXR_RXFULL |
|
||||||
|
XUARTPS_IXR_TOUT;
|
||||||
|
/* Write the mask to the IER Register */
|
||||||
|
XUartPs_WriteReg(XPS_UART1_BASEADDR, XUARTPS_IER_OFFSET, mask);
|
||||||
|
/* Write the inverse of the Mask to the IDR register */
|
||||||
|
XUartPs_WriteReg(XPS_UART1_BASEADDR, XUARTPS_IDR_OFFSET, (~mask));
|
||||||
|
|
||||||
|
/* Enable the interrupt for the UART1 in the interrupt controller. */
|
||||||
|
XScuGic_Enable(&xInterruptController, XPAR_XUARTPS_1_INTR);
|
||||||
|
}
|
||||||
|
|
||||||
int uart0_read(char *ptr, int len) {
|
int uart0_read(char *ptr, int len) {
|
||||||
// TODO for blocking, if first call was successfull, further calls need to be delay=0
|
// TODO for blocking, if first call was successfull, further calls need to be delay=0
|
||||||
int received = 0;
|
int received = 0;
|
||||||
@ -90,3 +163,18 @@ int uart0_read(char *ptr, int len) {
|
|||||||
}
|
}
|
||||||
return received;
|
return received;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int uart1_read(char *ptr, int len) {
|
||||||
|
// TODO for blocking, if first call was successfull, further calls need to be delay=0
|
||||||
|
int received = 0;
|
||||||
|
while (len > 0) {
|
||||||
|
BaseType_t result = xQueueReceive(uart1_receive_queue, ptr, 0);
|
||||||
|
if (result == pdFAIL) {
|
||||||
|
return received;
|
||||||
|
}
|
||||||
|
received++;
|
||||||
|
ptr++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
return received;
|
||||||
|
}
|
@ -2,3 +2,5 @@
|
|||||||
|
|
||||||
void uart0_enable_receiver();
|
void uart0_enable_receiver();
|
||||||
int uart0_read(char *ptr, int len);
|
int uart0_read(char *ptr, int len);
|
||||||
|
void uart1_enable_receiver();
|
||||||
|
int uart1_read(char *ptr, int len);
|
@ -498,6 +498,8 @@ void setup_rx_bds(xemacpsif_s *xemacpsif, XEmacPs_BdRing *rxring)
|
|||||||
|
|
||||||
void emacps_recv_handler(void *arg)
|
void emacps_recv_handler(void *arg)
|
||||||
{
|
{
|
||||||
|
outbyte('D');
|
||||||
|
|
||||||
struct pbuf *p;
|
struct pbuf *p;
|
||||||
XEmacPs_Bd *rxbdset, *curbdptr;
|
XEmacPs_Bd *rxbdset, *curbdptr;
|
||||||
struct xemac_s *xemac;
|
struct xemac_s *xemac;
|
||||||
@ -585,7 +587,7 @@ void emacps_recv_handler(void *arg)
|
|||||||
sys_sem_signal(&xemac->sem_rx_data_available);
|
sys_sem_signal(&xemac->sem_rx_data_available);
|
||||||
xInsideISR--;
|
xInsideISR--;
|
||||||
#endif
|
#endif
|
||||||
|
outbyte('M');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,9 +12,10 @@
|
|||||||
#include "hardware/interfaces.h"
|
#include "hardware/interfaces.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
struct lwip_sock *get_socket(int fd);
|
// Those three are a hack, but a quite performant one
|
||||||
|
struct lwip_sock *get_socket(int fd); // only works with a patched lwip
|
||||||
extern QueueHandle_t uart0_receive_queue;
|
extern QueueHandle_t uart0_receive_queue;
|
||||||
|
extern QueueHandle_t uart1_receive_queue;
|
||||||
|
|
||||||
void udp_echo_thread(void *_) {
|
void udp_echo_thread(void *_) {
|
||||||
vTaskDelay(5000 * portTICK_RATE_MS);
|
vTaskDelay(5000 * portTICK_RATE_MS);
|
||||||
@ -51,8 +52,8 @@ void udp_echo_thread(void *_) {
|
|||||||
xil_printf("no addr");
|
xil_printf("no addr");
|
||||||
}
|
}
|
||||||
|
|
||||||
int uart_sock = hw_device_open("uart0", 5);
|
int uart0_fd = hw_device_open("uart0", 5);
|
||||||
write(uart_sock, "1234", 4);
|
int uart1_fd = hw_device_open("uart1", 5);
|
||||||
|
|
||||||
// char buffer[] = {'1','2','3','4'};
|
// char buffer[] = {'1','2','3','4'};
|
||||||
// ret = sendto(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)
|
// ret = sendto(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)
|
||||||
@ -73,6 +74,7 @@ void udp_echo_thread(void *_) {
|
|||||||
|
|
||||||
xQueueAddToSet(queue_id, listening_set);
|
xQueueAddToSet(queue_id, listening_set);
|
||||||
xQueueAddToSet(uart0_receive_queue, listening_set);
|
xQueueAddToSet(uart0_receive_queue, listening_set);
|
||||||
|
xQueueAddToSet(uart1_receive_queue, listening_set);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
QueueSetMemberHandle_t readable =
|
QueueSetMemberHandle_t readable =
|
||||||
@ -80,8 +82,8 @@ void udp_echo_thread(void *_) {
|
|||||||
|
|
||||||
if (readable == queue_id) {
|
if (readable == queue_id) {
|
||||||
socklen_t peer_len = sizeof(peer_addr);
|
socklen_t peer_len = sizeof(peer_addr);
|
||||||
ret = lwip_recvfrom(sock, rec_buffer, sizeof(rec_buffer), 0, (struct sockaddr *) &peer_addr,
|
ret = lwip_recvfrom(sock, rec_buffer, sizeof(rec_buffer), 0,
|
||||||
&peer_len);
|
(struct sockaddr *)&peer_addr, &peer_len);
|
||||||
if (peer_len > sizeof(peer_addr)) {
|
if (peer_len > sizeof(peer_addr)) {
|
||||||
xil_printf("invalid peer");
|
xil_printf("invalid peer");
|
||||||
continue;
|
continue;
|
||||||
@ -93,14 +95,30 @@ void udp_echo_thread(void *_) {
|
|||||||
switch (port) {
|
switch (port) {
|
||||||
case 8100:
|
case 8100:
|
||||||
xil_printf("udp rec 8100 len: %i\n", ret);
|
xil_printf("udp rec 8100 len: %i\n", ret);
|
||||||
write(uart_sock, rec_buffer, ret);
|
write(uart0_fd, rec_buffer, ret);
|
||||||
|
break;
|
||||||
|
case 8101:
|
||||||
|
xil_printf("udp rec 8101 len: %i\n", ret);
|
||||||
|
write(uart1_fd, rec_buffer, ret);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
xil_printf("invalid port %i\n", port);
|
xil_printf("invalid port %i\n", port);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else if (readable == uart1_receive_queue) {
|
||||||
|
ret = read(uart1_fd, rec_buffer, sizeof(rec_buffer));
|
||||||
|
// Do not send empty packets
|
||||||
|
if (ret <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
xil_printf("uart got %i\n", ret);
|
||||||
|
peer_addr.sin_port = htons(8101);
|
||||||
|
|
||||||
|
// TODO sending 1 byte gives invalid UDP checksum
|
||||||
|
lwip_sendto(sock, rec_buffer, ret, 0, (struct sockaddr *)&peer_addr,
|
||||||
|
sizeof(peer_addr));
|
||||||
} else if (readable == uart0_receive_queue) {
|
} else if (readable == uart0_receive_queue) {
|
||||||
ret = read(uart_sock, rec_buffer, sizeof(rec_buffer));
|
ret = read(uart0_fd, rec_buffer, sizeof(rec_buffer));
|
||||||
xil_printf("uart got %i\n", ret);
|
xil_printf("uart got %i\n", ret);
|
||||||
|
|
||||||
// Do not send empty packets
|
// Do not send empty packets
|
||||||
@ -109,9 +127,9 @@ void udp_echo_thread(void *_) {
|
|||||||
}
|
}
|
||||||
peer_addr.sin_port = htons(8100);
|
peer_addr.sin_port = htons(8100);
|
||||||
|
|
||||||
//TODO sending 1 byte gives invalid UDP checksum
|
// TODO sending 1 byte gives invalid UDP checksum
|
||||||
lwip_sendto(sock, rec_buffer, ret, 0, (struct sockaddr *)&peer_addr,
|
lwip_sendto(sock, rec_buffer, ret, 0, (struct sockaddr *)&peer_addr,
|
||||||
sizeof(peer_addr));
|
sizeof(peer_addr));
|
||||||
} else {
|
} else {
|
||||||
xil_printf("invalid handle");
|
xil_printf("invalid handle");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user