Skip to content

Commit 85e54b0

Browse files
committed
use TUD_EPBUF_DEF to declare buffer memory for midi
1 parent c370c70 commit 85e54b0

File tree

5 files changed

+115
-122
lines changed

5 files changed

+115
-122
lines changed

src/class/midi/midi_device.c

Lines changed: 70 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -68,49 +68,45 @@ typedef struct {
6868
osal_mutex_def_t rx_ff_mutex;
6969
osal_mutex_def_t tx_ff_mutex;
7070
#endif
71-
72-
// Endpoint Transfer buffer
73-
union {
74-
CFG_TUD_MEM_ALIGN uint8_t epout_buf[CFG_TUD_MIDI_EP_BUFSIZE];
75-
TUD_DCACHE_PADDING;
76-
};
77-
union {
78-
CFG_TUD_MEM_ALIGN uint8_t epin_buf[CFG_TUD_MIDI_EP_BUFSIZE];
79-
TUD_DCACHE_PADDING;
80-
};
8171
} midid_interface_t;
8272

8373
#define ITF_MEM_RESET_SIZE offsetof(midid_interface_t, rx_ff)
8474

75+
// Endpoint Transfer buffer
76+
CFG_TUD_MEM_SECTION static struct {
77+
TUD_EPBUF_DEF(epin, CFG_TUD_MIDI_EP_BUFSIZE);
78+
TUD_EPBUF_DEF(epout, CFG_TUD_MIDI_EP_BUFSIZE);
79+
} _midid_epbuf[CFG_TUD_MIDI];
80+
8581
//--------------------------------------------------------------------+
8682
// INTERNAL OBJECT & FUNCTION DECLARATION
8783
//--------------------------------------------------------------------+
88-
CFG_TUD_MEM_SECTION midid_interface_t _midid_itf[CFG_TUD_MIDI];
84+
static midid_interface_t _midid_itf[CFG_TUD_MIDI];
8985

9086
bool tud_midi_n_mounted (uint8_t itf) {
9187
midid_interface_t* midi = &_midid_itf[itf];
9288
return midi->ep_in && midi->ep_out;
9389
}
9490

95-
static void _prep_out_transaction (midid_interface_t* p_midi)
96-
{
97-
uint8_t const rhport = 0;
91+
static void _prep_out_transaction(uint8_t idx) {
92+
const uint8_t rhport = 0;
93+
midid_interface_t* p_midi = &_midid_itf[idx];
9894
uint16_t available = tu_fifo_remaining(&p_midi->rx_ff);
9995

10096
// Prepare for incoming data but only allow what we can store in the ring buffer.
10197
// TODO Actually we can still carry out the transfer, keeping count of received bytes
10298
// and slowly move it to the FIFO when read().
10399
// This pre-check reduces endpoint claiming
104-
TU_VERIFY(available >= sizeof(p_midi->epout_buf), );
100+
TU_VERIFY(available >= sizeof(_midid_epbuf[idx].epout), );
105101

106102
// claim endpoint
107103
TU_VERIFY(usbd_edpt_claim(rhport, p_midi->ep_out), );
108104

109105
// fifo can be changed before endpoint is claimed
110106
available = tu_fifo_remaining(&p_midi->rx_ff);
111107

112-
if ( available >= sizeof(p_midi->epout_buf) ) {
113-
usbd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, sizeof(p_midi->epout_buf));
108+
if ( available >= CFG_TUD_MIDI_EP_BUFSIZE ) {
109+
usbd_edpt_xfer(rhport, p_midi->ep_out, _midid_epbuf[idx].epout, CFG_TUD_MIDI_EP_BUFSIZE);
114110
}else
115111
{
116112
// Release endpoint since we don't make any transfer
@@ -126,7 +122,7 @@ uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num)
126122
(void) cable_num;
127123

128124
midid_interface_t* midi = &_midid_itf[itf];
129-
midid_stream_t const* stream = &midi->stream_read;
125+
const midid_stream_t* stream = &midi->stream_read;
130126

131127
// when using with packet API stream total & index are both zero
132128
return tu_fifo_count(&midi->rx_ff) + (uint8_t) (stream->total - stream->index);
@@ -207,40 +203,40 @@ bool tud_midi_n_packet_read (uint8_t itf, uint8_t packet[4])
207203
midid_interface_t* midi = &_midid_itf[itf];
208204
TU_VERIFY(midi->ep_out);
209205

210-
uint32_t const num_read = tu_fifo_read_n(&midi->rx_ff, packet, 4);
211-
_prep_out_transaction(midi);
206+
const uint32_t num_read = tu_fifo_read_n(&midi->rx_ff, packet, 4);
207+
_prep_out_transaction(itf);
212208
return (num_read == 4);
213209
}
214210

215211
//--------------------------------------------------------------------+
216212
// WRITE API
217213
//--------------------------------------------------------------------+
218214

219-
static uint32_t write_flush(midid_interface_t* midi)
220-
{
221-
// No data to send
222-
if ( !tu_fifo_count(&midi->tx_ff) ) return 0;
215+
static uint32_t write_flush(uint8_t idx) {
216+
midid_interface_t* midi = &_midid_itf[idx];
223217

224-
uint8_t const rhport = 0;
218+
if (!tu_fifo_count(&midi->tx_ff)) {
219+
return 0; // No data to send
220+
}
221+
222+
const uint8_t rhport = 0;
225223

226224
// skip if previous transfer not complete
227225
TU_VERIFY( usbd_edpt_claim(rhport, midi->ep_in), 0 );
228226

229-
uint16_t count = tu_fifo_read_n(&midi->tx_ff, midi->epin_buf, CFG_TUD_MIDI_EP_BUFSIZE);
227+
uint16_t count = tu_fifo_read_n(&midi->tx_ff, _midid_epbuf[idx].epin, CFG_TUD_MIDI_EP_BUFSIZE);
230228

231-
if (count)
232-
{
233-
TU_ASSERT( usbd_edpt_xfer(rhport, midi->ep_in, midi->epin_buf, count), 0 );
229+
if (count) {
230+
TU_ASSERT( usbd_edpt_xfer(rhport, midi->ep_in, _midid_epbuf[idx].epin, count), 0 );
234231
return count;
235-
}else
236-
{
232+
}else {
237233
// Release endpoint since we don't make any transfer
238234
usbd_edpt_release(rhport, midi->ep_in);
239235
return 0;
240236
}
241237
}
242238

243-
uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize)
239+
uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t* buffer, uint32_t bufsize)
244240
{
245241
midid_interface_t* midi = &_midid_itf[itf];
246242
TU_VERIFY(midi->ep_in, 0);
@@ -250,14 +246,13 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const*
250246
uint32_t i = 0;
251247
while ( (i < bufsize) && (tu_fifo_remaining(&midi->tx_ff) >= 4) )
252248
{
253-
uint8_t const data = buffer[i];
249+
const uint8_t data = buffer[i];
254250
i++;
255251

256252
if ( stream->index == 0 )
257253
{
258254
//------------- New event packet -------------//
259-
260-
uint8_t const msg = data >> 4;
255+
const uint8_t msg = data >> 4;
261256

262257
stream->index = 2;
263258
stream->buffer[1] = data;
@@ -342,9 +337,11 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const*
342337
if ( stream->index == stream->total )
343338
{
344339
// zeroes unused bytes
345-
for(uint8_t idx = stream->total; idx < 4; idx++) stream->buffer[idx] = 0;
340+
for (uint8_t idx = stream->total; idx < 4; idx++) {
341+
stream->buffer[idx] = 0;
342+
}
346343

347-
uint16_t const count = tu_fifo_write_n(&midi->tx_ff, stream->buffer, 4);
344+
const uint16_t count = tu_fifo_write_n(&midi->tx_ff, stream->buffer, 4);
348345

349346
// complete current event packet, reset stream
350347
stream->index = stream->total = 0;
@@ -354,20 +351,21 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const*
354351
}
355352
}
356353

357-
write_flush(midi);
354+
write_flush(itf);
358355

359356
return i;
360357
}
361358

362-
bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4])
363-
{
359+
bool tud_midi_n_packet_write (uint8_t itf, const uint8_t packet[4]) {
364360
midid_interface_t* midi = &_midid_itf[itf];
365361
TU_VERIFY(midi->ep_in);
366362

367-
if (tu_fifo_remaining(&midi->tx_ff) < 4) return false;
363+
if (tu_fifo_remaining(&midi->tx_ff) < 4) {
364+
return false;
365+
}
368366

369367
tu_fifo_write_n(&midi->tx_ff, packet, 4);
370-
write_flush(midi);
368+
write_flush(itf);
371369

372370
return true;
373371
}
@@ -431,15 +429,15 @@ void midid_reset(uint8_t rhport)
431429
}
432430
}
433431

434-
uint16_t midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t max_len)
432+
uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint16_t max_len)
435433
{
436434
// 1st Interface is Audio Control v1
437435
TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass &&
438436
AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass &&
439437
AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol, 0);
440438

441439
uint16_t drv_len = tu_desc_len(desc_itf);
442-
uint8_t const * p_desc = tu_desc_next(desc_itf);
440+
const uint8_t* p_desc = tu_desc_next(desc_itf);
443441

444442
// Skip Class Specific descriptors
445443
while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len )
@@ -450,19 +448,18 @@ uint16_t midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint
450448

451449
// 2nd Interface is MIDI Streaming
452450
TU_VERIFY(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0);
453-
tusb_desc_interface_t const * desc_midi = (tusb_desc_interface_t const *) p_desc;
451+
const tusb_desc_interface_t* desc_midi = (const tusb_desc_interface_t*) p_desc;
454452

455453
TU_VERIFY(TUSB_CLASS_AUDIO == desc_midi->bInterfaceClass &&
456454
AUDIO_SUBCLASS_MIDI_STREAMING == desc_midi->bInterfaceSubClass &&
457455
AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_midi->bInterfaceProtocol, 0);
458456

459457
// Find available interface
460458
midid_interface_t * p_midi = NULL;
461-
for(uint8_t i=0; i<CFG_TUD_MIDI; i++)
462-
{
463-
if ( _midid_itf[i].ep_in == 0 && _midid_itf[i].ep_out == 0 )
464-
{
465-
p_midi = &_midid_itf[i];
459+
uint8_t idx;
460+
for(idx=0; idx<CFG_TUD_MIDI; idx++) {
461+
if ( _midid_itf[idx].ep_in == 0 && _midid_itf[idx].ep_out == 0 ) {
462+
p_midi = &_midid_itf[idx];
466463
break;
467464
}
468465
}
@@ -481,8 +478,8 @@ uint16_t midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint
481478
{
482479
if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) )
483480
{
484-
TU_ASSERT(usbd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), 0);
485-
uint8_t ep_addr = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress;
481+
TU_ASSERT(usbd_edpt_open(rhport, (const tusb_desc_endpoint_t*) p_desc), 0);
482+
uint8_t ep_addr = ((const tusb_desc_endpoint_t*) p_desc)->bEndpointAddress;
486483

487484
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN)
488485
{
@@ -503,63 +500,55 @@ uint16_t midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint
503500
}
504501

505502
// Prepare for incoming data
506-
_prep_out_transaction(p_midi);
503+
_prep_out_transaction(idx);
507504

508505
return drv_len;
509506
}
510507

511508
// Invoked when a control transfer occurred on an interface of this class
512509
// Driver response accordingly to the request and the transfer stage (setup/data/ack)
513510
// return false to stall control endpoint (e.g unsupported request)
514-
bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request)
515-
{
516-
(void) rhport;
517-
(void) stage;
518-
(void) request;
519-
520-
// driver doesn't support any request yet
521-
return false;
511+
bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t* request) {
512+
(void) rhport; (void) stage; (void) request;
513+
return false; // driver doesn't support any request yet
522514
}
523515

524516
bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
525517
{
526518
(void) result;
527519
(void) rhport;
528520

529-
uint8_t itf;
521+
uint8_t idx;
530522
midid_interface_t* p_midi;
531523

532524
// Identify which interface to use
533-
for (itf = 0; itf < CFG_TUD_MIDI; itf++)
534-
{
535-
p_midi = &_midid_itf[itf];
536-
if ( ( ep_addr == p_midi->ep_out ) || ( ep_addr == p_midi->ep_in ) ) break;
525+
for (idx = 0; idx < CFG_TUD_MIDI; idx++) {
526+
p_midi = &_midid_itf[idx];
527+
if ((ep_addr == p_midi->ep_out) || (ep_addr == p_midi->ep_in)) {
528+
break;
529+
}
537530
}
538-
TU_ASSERT(itf < CFG_TUD_MIDI);
531+
TU_ASSERT(idx < CFG_TUD_MIDI);
539532

540533
// receive new data
541-
if ( ep_addr == p_midi->ep_out )
542-
{
543-
tu_fifo_write_n(&p_midi->rx_ff, p_midi->epout_buf, (uint16_t) xferred_bytes);
534+
if (ep_addr == p_midi->ep_out) {
535+
tu_fifo_write_n(&p_midi->rx_ff, _midid_epbuf[idx].epout, (uint16_t)xferred_bytes);
544536

545537
// invoke receive callback if available
546-
if (tud_midi_rx_cb) tud_midi_rx_cb(itf);
538+
if (tud_midi_rx_cb) {
539+
tud_midi_rx_cb(idx);
540+
}
547541

548542
// prepare for next
549543
// TODO for now ep_out is not used by public API therefore there is no race condition,
550544
// and does not need to claim like ep_in
551-
_prep_out_transaction(p_midi);
552-
}
553-
else if ( ep_addr == p_midi->ep_in )
554-
{
555-
if (0 == write_flush(p_midi))
556-
{
545+
_prep_out_transaction(idx);
546+
} else if (ep_addr == p_midi->ep_in) {
547+
if (0 == write_flush(idx)) {
557548
// If there is no data left, a ZLP should be sent if
558549
// xferred_bytes is multiple of EP size and not zero
559-
if ( !tu_fifo_count(&p_midi->tx_ff) && xferred_bytes && (0 == (xferred_bytes % CFG_TUD_MIDI_EP_BUFSIZE)) )
560-
{
561-
if ( usbd_edpt_claim(rhport, p_midi->ep_in) )
562-
{
550+
if (!tu_fifo_count(&p_midi->tx_ff) && xferred_bytes && (0 == (xferred_bytes % CFG_TUD_MIDI_EP_BUFSIZE))) {
551+
if (usbd_edpt_claim(rhport, p_midi->ep_in)) {
563552
usbd_edpt_xfer(rhport, p_midi->ep_in, NULL, 0);
564553
}
565554
}

src/common/tusb_common.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,6 @@
5858
// Generate a mask with bit from high (31) to low (0) set, e.g TU_GENMASK(3, 0) = 0b1111
5959
#define TU_GENMASK(h, l) ( (UINT32_MAX << (l)) & (UINT32_MAX >> (31 - (h))) )
6060

61-
// DCache padding for variable to occupy full cache line
62-
#define TUD_DCACHE_PADDING uint8_t TU_XSTRCAT(dcache_padding_, _TU_COUNTER_)[CFG_TUD_MEM_DCACHE_ENABLE ? CFG_TUD_MEM_DCACHE_LINE_SIZE : 1]
63-
6461
//--------------------------------------------------------------------+
6562
// Includes
6663
//--------------------------------------------------------------------+
@@ -179,7 +176,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned32(uint32_t value) { retur
179176
TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned64(uint64_t value) { return (value & 0x3FUL) == 0; }
180177

181178
//------------- Mathematics -------------//
182-
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_ceil(uint32_t v, uint32_t d) { return (v + d -1)/d; }
179+
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_ceil(uint32_t v, uint32_t d) { return TU_DIV_CEIL(v, d); }
183180

184181
// log2 of a value is its MSB's position
185182
// TODO use clz TODO remove

src/common/tusb_types.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@
3535
extern "C" {
3636
#endif
3737

38+
// DCache padding for variable to occupy full cache line
39+
#define TUD_DCACHE_PADDING uint8_t TU_XSTRCAT(dcache_padding_, _TU_COUNTER_)[CFG_TUD_MEM_DCACHE_ENABLE ? CFG_TUD_MEM_DCACHE_LINE_SIZE : 1]
40+
41+
#define TUD_EPBUF_DEF(_name, _size) \
42+
union { \
43+
CFG_TUD_MEM_ALIGN uint8_t _name[_size]; \
44+
uint8_t _name##_dcache_padding[CFG_TUD_MEM_DCACHE_ENABLE ? (TU_DIV_CEIL(_size, CFG_TUD_MEM_DCACHE_LINE_SIZE) * CFG_TUD_MEM_DCACHE_LINE_SIZE) : 1]; \
45+
};
46+
47+
3848
/*------------------------------------------------------------------*/
3949
/* CONSTANTS
4050
*------------------------------------------------------------------*/

0 commit comments

Comments
 (0)