forked from PAWPAW-Mirror/lib_xua
Plug in variable size queue implementation for saving buffer space in iAP.
This commit is contained in:
@@ -1,22 +1,49 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "queue.h"
|
#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
|
// 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->rdptr = 0;
|
||||||
q->wrptr = 0;
|
q->wrptr = 0;
|
||||||
q->data = (uintptr_t)arr;
|
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;
|
q->mask = size - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern inline void enqueue(queue *q, unsigned value) {
|
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++;
|
q->wrptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern inline unsigned dequeue(queue *q) {
|
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++;
|
q->rdptr++;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@@ -41,7 +68,17 @@ extern inline int space(queue *q) {
|
|||||||
|
|
||||||
void dump(queue *q) {
|
void dump(queue *q) {
|
||||||
for (int i = q->rdptr; i != q->wrptr; i++) {
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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 rdptr; // Using absolute indices which count reads and writes so this needs to be considered when accessing.
|
||||||
int wrptr;
|
int wrptr;
|
||||||
int size;
|
int size;
|
||||||
|
int element_size;
|
||||||
int mask;
|
int mask;
|
||||||
} queue;
|
} 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);
|
void enqueue(REFERENCE_PARAM(queue, q), unsigned value);
|
||||||
unsigned dequeue(REFERENCE_PARAM(queue, q));
|
unsigned dequeue(REFERENCE_PARAM(queue, q));
|
||||||
int isempty(REFERENCE_PARAM(queue, q));
|
int isempty(REFERENCE_PARAM(queue, q));
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <xs1.h>
|
#include <xs1.h>
|
||||||
#include <xclib.h>
|
#include <xclib.h>
|
||||||
#include <print.h>
|
#include <print.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include "usb_midi.h"
|
#include "usb_midi.h"
|
||||||
#include "midiinparse.h"
|
#include "midiinparse.h"
|
||||||
#include "midioutparse.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
|
// One place buffer for data going out to host
|
||||||
queue midi_to_host_fifo;
|
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;
|
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)
|
// the symbol fifo (to go out of uart)
|
||||||
queue symbol_fifo;
|
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;
|
unsigned rxPT, txPT;
|
||||||
int midi_from_host_overflow = 0;
|
int midi_from_host_overflow = 0;
|
||||||
|
|
||||||
//configure_clock_rate(clk_midi, 100, 1);
|
//configure_clock_rate(clk_midi, 100, 1);
|
||||||
init_queue(symbol_fifo, symbol_fifo_arr, USB_MIDI_DEVICE_OUT_FIFO_SIZE);
|
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);
|
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_out_port_no_ready(p_midi_out, clk_midi, 1);
|
||||||
configure_in_port(p_midi_in, clk_midi);
|
configure_in_port(p_midi_in, clk_midi);
|
||||||
|
|||||||
Reference in New Issue
Block a user