From 197b04b2f2e68976ec1de0d7df4636ea1d8dfec1 Mon Sep 17 00:00:00 2001
From: Brendan Bartels <bbartels@iastate.edu>
Date: Sat, 22 Apr 2017 01:40:44 -0500
Subject: [PATCH] wip: fix more issues in hw_impl_zybo_uart.c

---
 .../real_quad/src/hw_impl_zybo_uart.c         | 37 ++++++++++++-------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_uart.c b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_uart.c
index 18c17af0a..0baaab96c 100644
--- a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_uart.c
+++ b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_uart.c
@@ -8,22 +8,28 @@ void uart_interrupt_handler(XUartPs *InstancePtr);
 int SetupInterruptSystem(XUartPs *UartInstancePtr, u16 UartIntrId, Xil_ExceptionHandler handler);
 void uart_interrupt_handler(XUartPs *InstancePtr);
 
-// Queue has to be global to be accessible to ISR
-static struct Queue queue;
-static volatile unsigned char buff[MAX_UART_BUFFER_SIZE];
-static XScuGic xscugic;
+struct UARTState {
+  struct Queue *queue;
+  XUartPs *inst;
+};
 
 int zybo_uart_reset(struct UARTDriver *self) {
   // Instantiate the Driver state
   if (self->state == NULL) {
-    self->state = malloc(sizeof(XUartPs));
-    if (self->state == NULL) {
-      return -1;
-    }
-    queue_init(&queue, buff, MAX_UART_BUFFER_SIZE);
+    self->state = malloc(sizeof(struct UARTState));
+    if (self->state == NULL) return -1;
+    self->state->inst = malloc(sizeof(XUartPs));
+    if (self->state->inst == NULL) return -1;
+
+    // We are cheating. We put the Queue on the callback field,
+    // because that was the only way we could get the Queue
+    // into this interupt handler. And the callback field was a void
+    // pointer so we can do whatever we want with it...
+    self->state->inst->CallBackRef = queue_malloc(MAX_UART_BUFFER_SIZE);
+    if (self->state->inst->CallBackRef == NULL) return -1;
   }
 
-  XUartPs *inst = self->state;;
+  XUartPs *inst = self->state->inst;
 
   // Configure XUartPs instance
   XUartPs_Config* config = XUartPs_LookupConfig(XPAR_PS7_UART_0_DEVICE_ID);
@@ -75,7 +81,9 @@ int zybo_uart_write(struct UARTDriver *self, unsigned char c) {\
 }
 
 int zybo_uart_read(struct UARTDriver *self, unsigned char *c) {
-  if (queue_remove(&queue, c)) return -1;
+  // We put the queue on the void pointer callback reference
+  struct Queue *queue = InstancePtr->CallBackRef;
+  if (queue_remove(queue, c)) return -1;
   else return 0;
 }
 
@@ -191,6 +199,9 @@ int XUartPs_SetBaudRate_ours(XUartPs *InstancePtr, u32 BaudRate)
 void uart_interrupt_handler(XUartPs *InstancePtr) {
   u32 IsrStatus;
 
+  // We put the queue on the void pointer callback reference
+  struct Queue *queue = InstancePtr->CallBackRef;
+
   /*
    * Read the interrupt ID register to determine which
    * interrupt is active
@@ -211,7 +222,7 @@ void uart_interrupt_handler(XUartPs *InstancePtr) {
 
   while (0 == (CsrRegister & XUARTPS_SR_RXEMPTY)) {
     u8 byte = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_FIFO_OFFSET);
-    queue_add(&queue, byte);
+    queue_add(queue, byte);
     CsrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_SR_OFFSET);
   }
 
@@ -241,7 +252,7 @@ void uart_interrupt_handler(XUartPs *InstancePtr) {
 int SetupInterruptSystem(XUartPs *UartInstancePtr, u16 UartIntrId, Xil_ExceptionHandler handler)
 {
 	int Status;
-
+	XScuGic xscugic;
 	XScuGic_Config *IntcConfig; /* Config for interrupt controller */
 
 	/* Initialize the interrupt controller driver */
-- 
GitLab