From 1e1cb9288d2a358cc857873c10a925e51fffef96 Mon Sep 17 00:00:00 2001 From: Russell Date: Tue, 6 Dec 2011 17:12:44 +0000 Subject: [PATCH] Plug in variable size queue implementation for saving buffer space in iAP. --- module_usb_midi/src/queue.c | 47 +++++++++++++++++++++++++++++---- module_usb_midi/src/queue.h | 3 ++- module_usb_midi/src/usb_midi.xc | 9 ++++--- 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/module_usb_midi/src/queue.c b/module_usb_midi/src/queue.c index 3d52a06e..1852b466 100644 --- a/module_usb_midi/src/queue.c +++ b/module_usb_midi/src/queue.c @@ -1,22 +1,49 @@ #include #include "queue.h" +// Queue implementation +// Offers no protection against adding when full or dequeueing when empty. +// Uses read and write counts for pointers to distinguish full and empty cases. +// Works from c and xc +// Must allocate the memory outside of this and pass it in to init_queue so can statically allocate +// Must work for different element sizes + // This presumes that the xc compiler will not re-use the mem passed to init_queue -void init_queue(queue *q, unsigned arr[], int size) { +void init_queue(queue *q, unsigned char arr[], int size, int element_size) { q->rdptr = 0; q->wrptr = 0; q->data = (uintptr_t)arr; - q->size = size; // presume that size is power of two + q->size = size; // in items, presume that size is power of two + q->element_size = element_size; // The size of each element in bytes q->mask = size - 1; } extern inline void enqueue(queue *q, unsigned value) { - ((unsigned *)q->data)[q->wrptr & q->mask] = value; + switch (q->element_size) { + case 4: + ((unsigned *)q->data)[q->wrptr & q->mask] = value; + break; + case 1: + ((unsigned char *)q->data)[q->wrptr & q->mask] = (unsigned char)value; + break; + default: + break; + } q->wrptr++; } extern inline unsigned dequeue(queue *q) { - unsigned retval = ((unsigned *)q->data)[q->rdptr & q->mask]; + unsigned retval; + switch (q->element_size) { + case 4: + retval = ((unsigned *)q->data)[q->rdptr & q->mask]; + break; + case 1: + retval = ((unsigned char *)q->data)[q->rdptr & q->mask]; + break; + default: + break; + } q->rdptr++; return retval; } @@ -41,7 +68,17 @@ extern inline int space(queue *q) { void dump(queue *q) { for (int i = q->rdptr; i != q->wrptr; i++) { - printf("a[%d] = %d\n", i & q->mask, ((unsigned *)q->data)[i & q->mask]); + switch (q->element_size) { + case 4: + printf("a[%d] = %d\n", i & q->mask, ((unsigned *)q->data)[i & q->mask]); + break; + case 1: + printf("a[%d] = %d\n", i & q->mask, ((unsigned char *)q->data)[i & q->mask]); + break; + default: + break; + } } } + diff --git a/module_usb_midi/src/queue.h b/module_usb_midi/src/queue.h index 615cac67..1e04c8d0 100644 --- a/module_usb_midi/src/queue.h +++ b/module_usb_midi/src/queue.h @@ -9,10 +9,11 @@ typedef struct queue { int rdptr; // Using absolute indices which count reads and writes so this needs to be considered when accessing. int wrptr; int size; + int element_size; int mask; } queue; -void init_queue(REFERENCE_PARAM(queue, q), unsigned arr[], int size); +void init_queue(REFERENCE_PARAM(queue, q), unsigned char arr[], int size, int element_size); void enqueue(REFERENCE_PARAM(queue, q), unsigned value); unsigned dequeue(REFERENCE_PARAM(queue, q)); int isempty(REFERENCE_PARAM(queue, q)); diff --git a/module_usb_midi/src/usb_midi.xc b/module_usb_midi/src/usb_midi.xc index e329d91d..a44a565a 100644 --- a/module_usb_midi/src/usb_midi.xc +++ b/module_usb_midi/src/usb_midi.xc @@ -1,6 +1,7 @@ #include #include #include +#include #include "usb_midi.h" #include "midiinparse.h" #include "midioutparse.h" @@ -91,7 +92,7 @@ chanend c_iap, chanend ?c_i2c // iOS stuff // One place buffer for data going out to host queue midi_to_host_fifo; - unsigned midi_to_host_fifo_arr[1]; + unsigned char midi_to_host_fifo_arr[4]; // Used for 32bit USB MIDI events unsigned outputting_symbol, outputted_symbol; @@ -99,14 +100,14 @@ chanend c_iap, chanend ?c_i2c // iOS stuff // the symbol fifo (to go out of uart) queue symbol_fifo; - unsigned symbol_fifo_arr[USB_MIDI_DEVICE_OUT_FIFO_SIZE]; + unsigned char symbol_fifo_arr[USB_MIDI_DEVICE_OUT_FIFO_SIZE * 4]; // Used for 32bit USB MIDI events unsigned rxPT, txPT; int midi_from_host_overflow = 0; //configure_clock_rate(clk_midi, 100, 1); - init_queue(symbol_fifo, symbol_fifo_arr, USB_MIDI_DEVICE_OUT_FIFO_SIZE); - init_queue(midi_to_host_fifo, midi_to_host_fifo_arr, 1); + init_queue(symbol_fifo, symbol_fifo_arr, USB_MIDI_DEVICE_OUT_FIFO_SIZE, 4); + init_queue(midi_to_host_fifo, midi_to_host_fifo_arr, 1, 4); configure_out_port_no_ready(p_midi_out, clk_midi, 1); configure_in_port(p_midi_in, clk_midi);