diff --git a/lib_xua/src/midi/queue.h b/lib_xua/src/midi/queue.h index af67e6e5..b056c309 100644 --- a/lib_xua/src/midi/queue.h +++ b/lib_xua/src/midi/queue.h @@ -14,6 +14,8 @@ typedef struct queue_t { unsigned mask; } queue_t; +#ifdef __XC__ + inline int is_power_of_2(unsigned x) { return x != 0 && (x & (x - 1)) == 0; } @@ -64,4 +66,6 @@ inline unsigned queue_space(const queue_t &q) { return q.size - queue_items(q); } +#endif // __XC__ + #endif /* QUEUE_H_ */ diff --git a/tests/conftest.py b/tests/conftest.py index 58ced38c..b1973ed1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,4 @@ -# Copyright 2022-2023 XMOS LIMITED. +# Copyright 2022-2024 XMOS LIMITED. # This Software is subject to the terms of the XMOS Public Licence: Version 1. import pytest import time diff --git a/tests/test_midi/src/app_midi_simple.xc b/tests/test_midi/src/app_midi_simple.xc index 5f86f1cd..eecae28b 100644 --- a/tests/test_midi/src/app_midi_simple.xc +++ b/tests/test_midi/src/app_midi_simple.xc @@ -36,7 +36,7 @@ on tile[MIDI_TILE] : clock clk_midi = CLKBLK_MIDI; #define TEST_COMMAND_FILE_TX "midi_tx_cmds.txt" #define TEST_COMMAND_FILE_RX "midi_rx_cmds.txt" -#define DEBUG 0 +#define DEBUG 0 #if DEBUG #define dprintf(...) printf(__VA_ARGS__) diff --git a/tests/xua_unit_tests/src/test_midi_queue/hid_report_descriptor.h b/tests/xua_unit_tests/src/test_midi_queue/hid_report_descriptor.h new file mode 100644 index 00000000..3824814e --- /dev/null +++ b/tests/xua_unit_tests/src/test_midi_queue/hid_report_descriptor.h @@ -0,0 +1,145 @@ +// Copyright 2021-2024 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#ifndef __hid_report_descriptor_h__ +#define __hid_report_descriptor_h__ + +#include "xua_hid_report.h" + +/* + * Define non-configurable items in the HID Report descriptor. + * (These are short items as the location field isn't relevant for them) + */ +static const USB_HID_Short_Item_t hidCollectionApplication = { + .header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_COLLECTION), + .data = { 0x01, 0x00 } }; +static const USB_HID_Short_Item_t hidCollectionEnd = { + .header = HID_REPORT_SET_HEADER(0, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_END_COLLECTION), + .data = { 0x00, 0x00 } }; +static const USB_HID_Short_Item_t hidCollectionLogical = { + .header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_COLLECTION), + .data = { 0x02, 0x00 } }; + +static const USB_HID_Short_Item_t hidInputConstArray = { + .header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT), + .data = { 0x01, 0x00 } }; +static const USB_HID_Short_Item_t hidInputDataVar = { + .header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT), + .data = { 0x02, 0x00 } }; + +static const USB_HID_Short_Item_t hidLogicalMaximum0 = { + .header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM), + .data = { 0x00, 0x00 } }; +static const USB_HID_Short_Item_t hidLogicalMaximum1 = { + .header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM), + .data = { 0x01, 0x00 } }; +static const USB_HID_Short_Item_t hidLogicalMinimum0 = { + .header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MINIMUM), + .data = { 0x00, 0x00 } }; + +static const USB_HID_Short_Item_t hidReportCount1 = { + .header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT), + .data = { 0x01, 0x00 } }; +static const USB_HID_Short_Item_t hidReportCount6 = { + .header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT), + .data = { 0x06, 0x00 } }; +static const USB_HID_Short_Item_t hidReportCount7 = { + .header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT), + .data = { 0x07, 0x00 } }; +static const USB_HID_Short_Item_t hidReportSize1 = { + .header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_SIZE), + .data = { 0x01, 0x00 } }; + +static const USB_HID_Short_Item_t hidUsageConsumerControl = { + .header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE), + .data = { 0x01, 0x00 } }; + +/* + * Define the HID Report Descriptor Item, Usage Page, Report ID and length for each HID Report + * For internal purposes, a report element with ID of 0 must be included if report IDs are not being used. + */ +static const USB_HID_Report_Element_t hidReportPageConsumer = { + .item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_USAGE_PAGE), + .item.data = { USB_HID_USAGE_PAGE_ID_CONSUMER, 0x00 }, + .location = HID_REPORT_SET_LOC( 0, 2, 0, 0 ) +}; + +/* + * Define configurable items in the HID Report descriptor. + */ +static USB_HID_Report_Element_t hidUsageByte0Bit0 = { + .item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE), + .item.data = { 0xE2, 0x00 }, + .location = HID_REPORT_SET_LOC(0, 0, 0, 0) +}; // Mute + +static USB_HID_Report_Element_t hidUsageByte1Bit7 = { + .item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE), + .item.data = { 0xEA, 0x00 }, + .location = HID_REPORT_SET_LOC(0, 0, 1, 7) +}; // Vol- +static USB_HID_Report_Element_t hidUsageByte1Bit0 = { + .item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE), + .item.data = { 0xE9, 0x00 }, + .location = HID_REPORT_SET_LOC(0, 0, 1, 0) +}; // Vol+ + +/* + * List the configurable elements in the HID Report descriptor. + */ +static USB_HID_Report_Element_t* const hidConfigurableElements[] = { + &hidUsageByte0Bit0, + &hidUsageByte1Bit0, + &hidUsageByte1Bit7 +}; + +/* + * List HID Reports, one per Report ID. This should be a usage page item with the relevant + * If not using report IDs - still have one with report ID 0 + */ +static const USB_HID_Report_Element_t* const hidReports[] = { + &hidReportPageConsumer +}; + +/* + * List all items in the HID Report descriptor. + */ +static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { + &(hidReportPageConsumer.item), + &hidUsageConsumerControl, + &hidCollectionApplication, + &hidReportSize1, + &hidLogicalMinimum0, + &hidCollectionLogical, // Byte 0 + &hidLogicalMaximum1, + &hidReportCount1, + &(hidUsageByte0Bit0.item), + &hidInputDataVar, + &hidLogicalMaximum0, + &hidReportCount7, + &hidInputConstArray, + &hidCollectionEnd, + &hidCollectionLogical, // Byte 1 + &hidLogicalMaximum1, + &hidReportCount1, + &(hidUsageByte1Bit0.item), + &hidInputDataVar, + &hidLogicalMaximum0, + &hidReportCount6, + &hidInputConstArray, + &hidReportCount1, + &hidLogicalMaximum1, + &(hidUsageByte1Bit7.item), + &hidInputDataVar, + &hidCollectionEnd, + &hidCollectionEnd +}; + +/* + * Define the number of HID Reports + * Due to XC not supporting designated initializers, this constant has a hard-coded value. + * It must equal ( sizeof hidReports / sizeof ( USB_HID_Report_Element_t* )) + */ +#define HID_REPORT_COUNT ( 1 ) + +#endif // __hid_report_descriptor_h__ diff --git a/tests/xua_unit_tests/src/test_midi_queue/test_midi_queue.c b/tests/xua_unit_tests/src/test_midi_queue/test_midi_queue.c new file mode 100644 index 00000000..07161054 --- /dev/null +++ b/tests/xua_unit_tests/src/test_midi_queue/test_midi_queue.c @@ -0,0 +1,25 @@ +// Copyright 2024 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. +#include +#include + +#include "xua_unit_tests.h" +#include "../../../lib_xua/src/midi/queue.h" + + +#define RANDOM_SEED 55378008 +#define USB_MIDI_DEVICE_OUT_FIFO_SIZE 1024 +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + +unsigned rndm = RANDOM_SEED; + + +void test_queue(void) { + queue_t symbol_fifo; + unsigned symbol_fifo_storage[USB_MIDI_DEVICE_OUT_FIFO_SIZE]; + queue_init_wrap(&symbol_fifo, ARRAY_SIZE(symbol_fifo_storage)); + + int empty = queue_is_empty_wrap(&symbol_fifo); + TEST_ASSERT_EQUAL_UINT32(1, empty); + +} \ No newline at end of file diff --git a/tests/xua_unit_tests/src/xua_unit_test_helper.xc b/tests/xua_unit_tests/src/xua_unit_test_helper.xc index 48f82d3f..611f95b7 100644 --- a/tests/xua_unit_tests/src/xua_unit_test_helper.xc +++ b/tests/xua_unit_tests/src/xua_unit_test_helper.xc @@ -7,6 +7,8 @@ #include #include "../../../lib_xua/src/midi/midiinparse.h" #include "../../../lib_xua/src/midi/midioutparse.h" +#include "../../../lib_xua/src/midi/queue.h" + #endif // __XC__ @@ -33,7 +35,7 @@ unsigned random(unsigned &x){ return x; } -// Wrappers for midi parse because C doesn't support return tuples +////////////////////// Wrappers for midi parse because C doesn't support return tuples void midi_in_parse_wrap(void * unsafe mips, unsigned cable_number, unsigned char b, unsigned * unsafe valid, unsigned *unsafe packed){ unsafe{ struct midi_in_parse_state * unsafe ptr = mips; @@ -53,3 +55,57 @@ void reset_midi_state_wrap(void * unsafe mips){ reset_midi_state(*ptr); } } + +/////////////////////// Wrappers for queue test + + +void queue_init_wrap(queue_t *q, unsigned size) { + unsafe{ + queue_init(*q, size); + } +} + +int queue_is_empty_wrap(queue_t *unsafe q) { + unsafe{ + return queue_is_empty(*q); + } +} + +int queue_is_full_wrap(queue_t *unsafe q) { + unsafe{ + return queue_is_full(*q); + } +} + +/* +inline void queue_push_word(queue_t &q, unsigned array[], unsigned data) +{ + assert(!queue_is_full(q)); + array[q.wrptr++ & q.mask] = data; +} + +inline unsigned queue_pop_word(queue_t &q, unsigned array[]) { + assert(!queue_is_empty(q)); + return array[q.rdptr++ & q.mask]; +} + +inline void queue_push_byte(queue_t &q, unsigned char array[], unsigned data) +{ + assert(!queue_is_full(q)); + array[q.wrptr++ & q.mask] = data; +} + +inline unsigned queue_pop_byte(queue_t &q, unsigned char array[]) { + assert(!queue_is_empty(q)); + return array[q.rdptr++ & q.mask]; +} + +inline unsigned queue_items(const queue_t &q) { + return q.wrptr - q.rdptr; +} + +inline unsigned queue_space(const queue_t &q) { + return q.size - queue_items(q); +} + +*/ \ No newline at end of file diff --git a/tests/xua_unit_tests/src/xua_unit_tests.h b/tests/xua_unit_tests/src/xua_unit_tests.h index 7763b97a..53cf0dcd 100644 --- a/tests/xua_unit_tests/src/xua_unit_tests.h +++ b/tests/xua_unit_tests/src/xua_unit_tests.h @@ -5,12 +5,19 @@ #include "unity.h" #include "xua_conf.h" +#include "../../../lib_xua/src/midi/queue.h" #ifndef __XC__ void midi_in_parse_wrap(void * mips, unsigned cable_number, unsigned char b, unsigned * valid, unsigned * packed); void midi_out_parse_wrap(unsigned tx_data, unsigned midi[3], unsigned * size); void reset_midi_state_wrap(void *mips); unsigned random(unsigned *x); + +void queue_init_wrap(queue_t *q, unsigned size); +int queue_is_empty_wrap(const queue_t *q); +int queue_is_full_wrap(const queue_t *q); + + #endif #endif /* XUA_UNIT_TESTS_H_ */