From f607a99127cc9e8dfc3f716f977e6c1bfb6f7c2d Mon Sep 17 00:00:00 2001 From: Martin Thierer Date: Tue, 20 Jul 2021 18:55:00 +0200 Subject: Send a ZLP if nothing to transfer and last transfer was EPSIZE --- src/class/vendor/vendor_device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 6718a97bf..5b58d85e1 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -61,6 +61,8 @@ typedef struct CFG_TUSB_MEM_SECTION static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; +CFG_TUSB_MEM_SECTION static bool last_in_transfer_was_epsize = false; + #define ITF_MEM_RESET_SIZE offsetof(vendord_interface_t, rx_ff) @@ -112,10 +114,11 @@ static bool maybe_transmit(vendord_interface_t* p_itf) TU_VERIFY( !usbd_edpt_busy(TUD_OPT_RHPORT, p_itf->ep_in) ); uint16_t count = tu_fifo_read_n(&p_itf->tx_ff, p_itf->epin_buf, CFG_TUD_VENDOR_EPSIZE); - if (count > 0) + if (count > 0 || last_in_transfer_was_epsize) { TU_ASSERT( usbd_edpt_xfer(TUD_OPT_RHPORT, p_itf->ep_in, p_itf->epin_buf, count) ); } + last_in_transfer_was_epsize = count && (count == CFG_TUD_VENDOR_EPSIZE); return true; } -- cgit v1.3.1 From cba327fc384ae730287b0ab620d1f7ef50b0da3b Mon Sep 17 00:00:00 2001 From: mndza Date: Fri, 30 Jun 2023 11:20:58 +0200 Subject: tusb_fifo: split constant address functions Due to a missed optimization in the compiler, code for constant address handling is being included in all builds. This change splits the code in different functions to avoid that. --- src/common/tusb_fifo.c | 402 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 260 insertions(+), 142 deletions(-) diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index a52c92267..323d3a754 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -55,16 +55,6 @@ TU_ATTR_ALWAYS_INLINE static inline void _ff_unlock(osal_mutex_t mutex) #endif -/** \enum tu_fifo_copy_mode_t - * \brief Write modes intended to allow special read and write functions to be able to - * copy data to and from USB hardware FIFOs as needed for e.g. STM32s and others - */ -typedef enum -{ - TU_FIFO_COPY_INC, ///< Copy from/to an increasing source/destination address - default mode - TU_FIFO_COPY_CST_FULL_WORDS, ///< Copy from/to a constant source/destination address - required for e.g. STM32 to write into USB hardware FIFO -} tu_fifo_copy_mode_t; - bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable) { // Limit index space to 2*depth - this allows for a fast "modulo" calculation @@ -148,7 +138,7 @@ static inline void _ff_push(tu_fifo_t* f, void const * app_buf, uint16_t rel) } // send n items to fifo WITHOUT updating write pointer -static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t wr_ptr, tu_fifo_copy_mode_t copy_mode) +static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t wr_ptr) { uint16_t const lin_count = f->depth - wr_ptr; uint16_t const wrap_count = n - lin_count; @@ -159,71 +149,78 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t // current buffer of fifo uint8_t* ff_buf = f->buffer + (wr_ptr * f->item_size); - switch (copy_mode) + if(n <= lin_count) { - case TU_FIFO_COPY_INC: - if(n <= lin_count) - { - // Linear only - memcpy(ff_buf, app_buf, n*f->item_size); - } - else - { - // Wrap around + // Linear only + memcpy(ff_buf, app_buf, n*f->item_size); + } + else + { + // Wrap around - // Write data to linear part of buffer - memcpy(ff_buf, app_buf, lin_bytes); + // Write data to linear part of buffer + memcpy(ff_buf, app_buf, lin_bytes); - // Write data wrapped around - // TU_ASSERT(nWrap_bytes <= f->depth, ); - memcpy(f->buffer, ((uint8_t const*) app_buf) + lin_bytes, wrap_bytes); - } - break; + // Write data wrapped around + // TU_ASSERT(nWrap_bytes <= f->depth, ); + memcpy(f->buffer, ((uint8_t const*) app_buf) + lin_bytes, wrap_bytes); + } +} - case TU_FIFO_COPY_CST_FULL_WORDS: - // Intended for hardware buffers from which it can be read word by word only - if(n <= lin_count) - { - // Linear only - _ff_push_const_addr(ff_buf, app_buf, n*f->item_size); - } - else - { - // Wrap around case - - // Write full words to linear part of buffer - uint16_t nLin_4n_bytes = lin_bytes & 0xFFFC; - _ff_push_const_addr(ff_buf, app_buf, nLin_4n_bytes); - ff_buf += nLin_4n_bytes; - - // There could be odd 1-3 bytes before the wrap-around boundary - uint8_t rem = lin_bytes & 0x03; - if (rem > 0) - { - volatile const uint32_t * rx_fifo = (volatile const uint32_t *) app_buf; - - uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem); - wrap_bytes -= remrem; - - uint32_t tmp32 = *rx_fifo; - uint8_t * src_u8 = ((uint8_t *) &tmp32); - - // Write 1-3 bytes before wrapped boundary - while(rem--) *ff_buf++ = *src_u8++; - - // Read more bytes to beginning to complete a word - ff_buf = f->buffer; - while(remrem--) *ff_buf++ = *src_u8++; - } - else - { - ff_buf = f->buffer; // wrap around to beginning - } - - // Write data wrapped part - if (wrap_bytes > 0) _ff_push_const_addr(ff_buf, app_buf, wrap_bytes); - } - break; +// send n items to fifo WITHOUT updating write pointer +// Version intended for hardware USB FIFOs where data is written to a constant address in full word copies +static void _ff_push_n_const_addr(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t wr_ptr) +{ + uint16_t const lin_count = f->depth - wr_ptr; + uint16_t const wrap_count = n - lin_count; + + uint16_t lin_bytes = lin_count * f->item_size; + uint16_t wrap_bytes = wrap_count * f->item_size; + + // current buffer of fifo + uint8_t* ff_buf = f->buffer + (wr_ptr * f->item_size); + + // Intended for hardware buffers from which it can be read word by word only + if(n <= lin_count) + { + // Linear only + _ff_push_const_addr(ff_buf, app_buf, n*f->item_size); + } + else + { + // Wrap around case + + // Write full words to linear part of buffer + uint16_t nLin_4n_bytes = lin_bytes & 0xFFFC; + _ff_push_const_addr(ff_buf, app_buf, nLin_4n_bytes); + ff_buf += nLin_4n_bytes; + + // There could be odd 1-3 bytes before the wrap-around boundary + uint8_t rem = lin_bytes & 0x03; + if (rem > 0) + { + volatile const uint32_t * rx_fifo = (volatile const uint32_t *) app_buf; + + uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem); + wrap_bytes -= remrem; + + uint32_t tmp32 = *rx_fifo; + uint8_t * src_u8 = ((uint8_t *) &tmp32); + + // Write 1-3 bytes before wrapped boundary + while(rem--) *ff_buf++ = *src_u8++; + + // Read more bytes to beginning to complete a word + ff_buf = f->buffer; + while(remrem--) *ff_buf++ = *src_u8++; + } + else + { + ff_buf = f->buffer; // wrap around to beginning + } + + // Write data wrapped part + if (wrap_bytes > 0) _ff_push_const_addr(ff_buf, app_buf, wrap_bytes); } } @@ -234,7 +231,7 @@ static inline void _ff_pull(tu_fifo_t* f, void * app_buf, uint16_t rel) } // get n items from fifo WITHOUT updating read pointer -static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr, tu_fifo_copy_mode_t copy_mode) +static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr) { uint16_t const lin_count = f->depth - rd_ptr; uint16_t const wrap_count = n - lin_count; // only used if wrapped @@ -245,76 +242,82 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr, // current buffer of fifo uint8_t* ff_buf = f->buffer + (rd_ptr * f->item_size); - switch (copy_mode) + if ( n <= lin_count ) { - case TU_FIFO_COPY_INC: - if ( n <= lin_count ) - { - // Linear only - memcpy(app_buf, ff_buf, n*f->item_size); - } - else - { - // Wrap around + // Linear only + memcpy(app_buf, ff_buf, n*f->item_size); + } + else + { + // Wrap around - // Read data from linear part of buffer - memcpy(app_buf, ff_buf, lin_bytes); + // Read data from linear part of buffer + memcpy(app_buf, ff_buf, lin_bytes); - // Read data wrapped part - memcpy((uint8_t*) app_buf + lin_bytes, f->buffer, wrap_bytes); - } - break; + // Read data wrapped part + memcpy((uint8_t*) app_buf + lin_bytes, f->buffer, wrap_bytes); + } +} - case TU_FIFO_COPY_CST_FULL_WORDS: - if ( n <= lin_count ) - { - // Linear only - _ff_pull_const_addr(app_buf, ff_buf, n*f->item_size); - } - else - { - // Wrap around case +// get n items from fifo WITHOUT updating read pointer +// Version intended for hardware USB FIFOs where data is read from a constant address in full word copies +static void _ff_pull_n_const_addr(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr) +{ + uint16_t const lin_count = f->depth - rd_ptr; + uint16_t const wrap_count = n - lin_count; // only used if wrapped - // Read full words from linear part of buffer - uint16_t lin_4n_bytes = lin_bytes & 0xFFFC; - _ff_pull_const_addr(app_buf, ff_buf, lin_4n_bytes); - ff_buf += lin_4n_bytes; + uint16_t lin_bytes = lin_count * f->item_size; + uint16_t wrap_bytes = wrap_count * f->item_size; - // There could be odd 1-3 bytes before the wrap-around boundary - uint8_t rem = lin_bytes & 0x03; - if (rem > 0) - { - volatile uint32_t * reg_tx = (volatile uint32_t *) app_buf; + // current buffer of fifo + uint8_t* ff_buf = f->buffer + (rd_ptr * f->item_size); - uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem); - wrap_bytes -= remrem; + if ( n <= lin_count ) + { + // Linear only + _ff_pull_const_addr(app_buf, ff_buf, n*f->item_size); + } + else + { + // Wrap around case - uint32_t tmp32=0; - uint8_t * dst_u8 = (uint8_t *)&tmp32; + // Read full words from linear part of buffer + uint16_t lin_4n_bytes = lin_bytes & 0xFFFC; + _ff_pull_const_addr(app_buf, ff_buf, lin_4n_bytes); + ff_buf += lin_4n_bytes; - // Read 1-3 bytes before wrapped boundary - while(rem--) *dst_u8++ = *ff_buf++; + // There could be odd 1-3 bytes before the wrap-around boundary + uint8_t rem = lin_bytes & 0x03; + if (rem > 0) + { + volatile uint32_t * reg_tx = (volatile uint32_t *) app_buf; - // Read more bytes from beginning to complete a word - ff_buf = f->buffer; - while(remrem--) *dst_u8++ = *ff_buf++; + uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem); + wrap_bytes -= remrem; - *reg_tx = tmp32; - } - else - { - ff_buf = f->buffer; // wrap around to beginning - } + uint32_t tmp32=0; + uint8_t * dst_u8 = (uint8_t *)&tmp32; - // Read data wrapped part - if (wrap_bytes > 0) _ff_pull_const_addr(app_buf, ff_buf, wrap_bytes); - } - break; + // Read 1-3 bytes before wrapped boundary + while(rem--) *dst_u8++ = *ff_buf++; + + // Read more bytes from beginning to complete a word + ff_buf = f->buffer; + while(remrem--) *dst_u8++ = *ff_buf++; - default: break; + *reg_tx = tmp32; + } + else + { + ff_buf = f->buffer; // wrap around to beginning + } + + // Read data wrapped part + if (wrap_bytes > 0) _ff_pull_const_addr(app_buf, ff_buf, wrap_bytes); } } + //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ @@ -435,7 +438,7 @@ static bool _tu_fifo_peek(tu_fifo_t* f, void * p_buffer, uint16_t wr_idx, uint16 // Works on local copies of w and r // Must be protected by mutexes since in case of an overflow read pointer gets modified -static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx, tu_fifo_copy_mode_t copy_mode) +static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx) { uint16_t cnt = _ff_count(f->depth, wr_idx, rd_idx); @@ -455,12 +458,40 @@ static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint1 uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); // Peek data - _ff_pull_n(f, p_buffer, n, rd_ptr, copy_mode); + _ff_pull_n(f, p_buffer, n, rd_ptr); return n; } -static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu_fifo_copy_mode_t copy_mode) +// Works on local copies of w and r +// Must be protected by mutexes since in case of an overflow read pointer gets modified +// Version intended for hardware USB FIFOs where data is read from a constant address in full word copies +static uint16_t _tu_fifo_peek_n_const_addr(tu_fifo_t* f, void * p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx) +{ + uint16_t cnt = _ff_count(f->depth, wr_idx, rd_idx); + + // nothing to peek + if ( cnt == 0 ) return 0; + + // Check overflow and correct if required + if ( cnt > f->depth ) + { + rd_idx = _ff_correct_read_index(f, wr_idx); + cnt = f->depth; + } + + // Check if we can read something at and after offset - if too less is available we read what remains + if ( cnt < n ) n = cnt; + + uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); + + // Peek data + _ff_pull_n_const_addr(f, p_buffer, n, rd_ptr); + + return n; +} + +static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n) { if ( n == 0 ) return 0; @@ -489,15 +520,87 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu if ( n >= f->depth ) { // Only copy last part - if ( copy_mode == TU_FIFO_COPY_INC ) + buf8 += (n - f->depth) * f->item_size; + n = f->depth; + + // We start writing at the read pointer's position since we fill the whole buffer + wr_idx = rd_idx; + } + else + { + uint16_t const overflowable_count = _ff_count(f->depth, wr_idx, rd_idx); + if (overflowable_count + n >= 2*f->depth) { - buf8 += (n - f->depth) * f->item_size; + // Double overflowed + // Index is bigger than the allowed range [0,2*depth) + // re-position write index to have a full fifo after pushed + wr_idx = advance_index(f->depth, rd_idx, f->depth - n); + + // TODO we should also shift out n bytes from read index since we avoid changing rd index !! + // However memmove() is expensive due to actual copying + wrapping consideration. + // Also race condition could happen anyway if read() is invoke while moving result in corrupted memory + // currently deliberately not implemented --> result in incorrect data read back }else { - // TODO should read from hw fifo to discard data, however reading an odd number could - // accidentally discard data. + // normal + single overflowed: + // Index is in the range of [0,2*depth) and thus detect and recoverable. Recovering is handled in read() + // Therefore we just increase write index + // we will correct (re-position) read index later on in fifo_read() function } + } + } + + if (n) + { + uint16_t wr_ptr = idx2ptr(f->depth, wr_idx); + + TU_LOG(TU_FIFO_DBG, "actual_n = %u, wr_ptr = %u", n, wr_ptr); + + // Write data + _ff_push_n(f, buf8, n, wr_ptr); + + // Advance index + f->wr_idx = advance_index(f->depth, wr_idx, n); + + TU_LOG(TU_FIFO_DBG, "\tnew_wr = %u\n", f->wr_idx); + } + _ff_unlock(f->mutex_wr); + + return n; +} + +static uint16_t _tu_fifo_write_n_const_addr(tu_fifo_t* f, const void * data, uint16_t n) +{ + if ( n == 0 ) return 0; + + _ff_lock(f->mutex_wr); + + uint16_t wr_idx = f->wr_idx; + uint16_t rd_idx = f->rd_idx; + + uint8_t const* buf8 = (uint8_t const*) data; + + TU_LOG(TU_FIFO_DBG, "rd = %3u, wr = %3u, count = %3u, remain = %3u, n = %3u: ", + rd_idx, wr_idx, _ff_count(f->depth, wr_idx, rd_idx), _ff_remaining(f->depth, wr_idx, rd_idx), n); + + if ( !f->overwritable ) + { + // limit up to full + uint16_t const remain = _ff_remaining(f->depth, wr_idx, rd_idx); + n = tu_min16(n, remain); + } + else + { + // In over-writable mode, fifo_write() is allowed even when fifo is full. In such case, + // oldest data in fifo i.e at read pointer data will be overwritten + // Note: we can modify read buffer contents but we must not modify the read index itself within a write function! + // Since it would end up in a race condition with read functions! + if ( n >= f->depth ) + { + // Only copy last part + // TODO should read from hw fifo to discard data, however reading an odd number could + // accidentally discard data. n = f->depth; // We start writing at the read pointer's position since we fill the whole buffer @@ -534,7 +637,7 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu TU_LOG(TU_FIFO_DBG, "actual_n = %u, wr_ptr = %u", n, wr_ptr); // Write data - _ff_push_n(f, buf8, n, wr_ptr, copy_mode); + _ff_push_n_const_addr(f, buf8, n, wr_ptr); // Advance index f->wr_idx = advance_index(f->depth, wr_idx, n); @@ -547,13 +650,28 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu return n; } -static uint16_t _tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n, tu_fifo_copy_mode_t copy_mode) +static uint16_t _tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n) +{ + _ff_lock(f->mutex_rd); + + // Peek the data + // f->rd_idx might get modified in case of an overflow so we can not use a local variable + n = _tu_fifo_peek_n(f, buffer, n, f->wr_idx, f->rd_idx); + + // Advance read pointer + f->rd_idx = advance_index(f->depth, f->rd_idx, n); + + _ff_unlock(f->mutex_rd); + return n; +} + +static uint16_t _tu_fifo_read_n_const_addr(tu_fifo_t* f, void * buffer, uint16_t n) { _ff_lock(f->mutex_rd); // Peek the data // f->rd_idx might get modified in case of an overflow so we can not use a local variable - n = _tu_fifo_peek_n(f, buffer, n, f->wr_idx, f->rd_idx, copy_mode); + n = _tu_fifo_peek_n_const_addr(f, buffer, n, f->wr_idx, f->rd_idx); // Advance read pointer f->rd_idx = advance_index(f->depth, f->rd_idx, n); @@ -723,12 +841,12 @@ bool tu_fifo_read(tu_fifo_t* f, void * buffer) /******************************************************************************/ uint16_t tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n) { - return _tu_fifo_read_n(f, buffer, n, TU_FIFO_COPY_INC); + return _tu_fifo_read_n(f, buffer, n); } uint16_t tu_fifo_read_n_const_addr_full_words(tu_fifo_t* f, void * buffer, uint16_t n) { - return _tu_fifo_read_n(f, buffer, n, TU_FIFO_COPY_CST_FULL_WORDS); + return _tu_fifo_read_n_const_addr(f, buffer, n); } /******************************************************************************/ @@ -770,7 +888,7 @@ bool tu_fifo_peek(tu_fifo_t* f, void * p_buffer) uint16_t tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n) { _ff_lock(f->mutex_rd); - uint16_t ret = _tu_fifo_peek_n(f, p_buffer, n, f->wr_idx, f->rd_idx, TU_FIFO_COPY_INC); + uint16_t ret = _tu_fifo_peek_n(f, p_buffer, n, f->wr_idx, f->rd_idx); _ff_unlock(f->mutex_rd); return ret; } @@ -835,7 +953,7 @@ bool tu_fifo_write(tu_fifo_t* f, const void * data) /******************************************************************************/ uint16_t tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n) { - return _tu_fifo_write_n(f, data, n, TU_FIFO_COPY_INC); + return _tu_fifo_write_n(f, data, n); } /******************************************************************************/ @@ -855,7 +973,7 @@ uint16_t tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n) /******************************************************************************/ uint16_t tu_fifo_write_n_const_addr_full_words(tu_fifo_t* f, const void * data, uint16_t n) { - return _tu_fifo_write_n(f, data, n, TU_FIFO_COPY_CST_FULL_WORDS); + return _tu_fifo_write_n_const_addr(f, data, n); } /******************************************************************************/ -- cgit v1.3.1 From d0bff6fd3ec9fc133032dea84732451d93d202b4 Mon Sep 17 00:00:00 2001 From: Xelus22 Date: Tue, 25 Jul 2023 23:53:55 +1000 Subject: initial add SOF supporpt to CH32V307 USB HS --- src/portable/wch/ch32v307/dcd_usbhs.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/portable/wch/ch32v307/dcd_usbhs.c b/src/portable/wch/ch32v307/dcd_usbhs.c index 3ad011cff..843643ef7 100644 --- a/src/portable/wch/ch32v307/dcd_usbhs.c +++ b/src/portable/wch/ch32v307/dcd_usbhs.c @@ -135,6 +135,19 @@ void dcd_remote_wakeup(uint8_t rhport) (void) rhport; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + if (en) + { + USBHSD->INT_EN |= USBHS_SOF_ACT_EN; + } + else + { + USBHSD->INT_EN &= ~(USBHS_SOF_ACT_EN); + } +} + void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { (void)rhport; @@ -332,7 +345,9 @@ void dcd_int_handler(uint8_t rhport) { xfer_ctl_t *xfer = XFER_CTL_BASE(end_num, tu_edpt_dir(endp)); - if (rx_token == PID_OUT) { + if (rx_token == PID_SOF) { + dcd_event_sof(rhport, USBHSD->FRAME_NO, true); + } else if (rx_token == PID_OUT) { uint16_t rx_len = USBHSD->RX_LEN; receive_packet(xfer, rx_len); -- cgit v1.3.1 From 0161955c22eccea62a783368073042154b3e5976 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Tue, 8 Aug 2023 17:48:45 +0000 Subject: Adding support for a SOF callback --- src/device/usbd.c | 4 ++++ src/device/usbd.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/device/usbd.c b/src/device/usbd.c index 9429cf664..3437159fb 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -597,6 +597,10 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) break; case DCD_EVENT_SOF: + TU_LOG_USBD("\r\n"); + if ( tud_sof_cb ) tud_sof_cb(event->rhport, event->sof.frame_count); + break; + default: TU_BREAKPOINT(); break; diff --git a/src/device/usbd.h b/src/device/usbd.h index b11c1a09d..db439e518 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -148,6 +148,9 @@ TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en); // Invoked when usb bus is resumed TU_ATTR_WEAK void tud_resume_cb(void); +// Invoked when a new (micro) frame started +TU_ATTR_WEAK void tud_sof_cb(uint8_t rhport, uint32_t frame_count); + // Invoked when received control request with VENDOR TYPE TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); -- cgit v1.3.1 From a98b21992263584ebced348b49f082c69171f0ff Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Tue, 8 Aug 2023 18:14:00 +0000 Subject: Remove port from SOF callback --- src/device/usbd.c | 3 ++- src/device/usbd.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 3437159fb..15ceec878 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1,3 +1,4 @@ + /* * The MIT License (MIT) * @@ -598,7 +599,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) case DCD_EVENT_SOF: TU_LOG_USBD("\r\n"); - if ( tud_sof_cb ) tud_sof_cb(event->rhport, event->sof.frame_count); + if ( tud_sof_cb ) tud_sof_cb(event->sof.frame_count); break; default: diff --git a/src/device/usbd.h b/src/device/usbd.h index db439e518..423cd7053 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -149,7 +149,7 @@ TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en); TU_ATTR_WEAK void tud_resume_cb(void); // Invoked when a new (micro) frame started -TU_ATTR_WEAK void tud_sof_cb(uint8_t rhport, uint32_t frame_count); +TU_ATTR_WEAK void tud_sof_cb(uint32_t frame_count); // Invoked when received control request with VENDOR TYPE TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); -- cgit v1.3.1 From 427ecbbc53f033586c898e130c07d8116258a73d Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Tue, 8 Aug 2023 23:33:47 +0200 Subject: Bad line break at start --- src/device/usbd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 15ceec878..226896b37 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1,4 +1,3 @@ - /* * The MIT License (MIT) * -- cgit v1.3.1 From 798ff807b3361a5859945cb23c3d0fd7d1a5679f Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 11 Aug 2023 18:04:34 +0200 Subject: removed obsolete tud_network_link_state_cb() --- src/class/net/ncm_device.c | 7 ------- src/class/net/net_device.h | 5 ----- test/fuzz/net_fuzz.cc | 10 +--------- 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 226c42c4e..dc086cf5c 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -337,11 +337,6 @@ static void ncm_report(void) } } -TU_ATTR_WEAK void tud_network_link_state_cb(bool state) -{ - (void)state; -} - // Handle class control request // return false to stall control endpoint (e.g unsupported request) bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) @@ -381,8 +376,6 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t ncm_report(); } } - - tud_network_link_state_cb(ncm_interface.itf_data_alt); } tud_control_status(rhport, request); diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h index 399916355..454fde861 100644 --- a/src/class/net/net_device.h +++ b/src/class/net/net_device.h @@ -96,11 +96,6 @@ void tud_network_init_cb(void); // TODO removed later since it is not part of tinyusb stack extern uint8_t tud_network_mac_address[6]; -//------------- NCM -------------// - -// callback to client providing optional indication of internal state of network driver -void tud_network_link_state_cb(bool state); - //--------------------------------------------------------------------+ // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+ diff --git a/test/fuzz/net_fuzz.cc b/test/fuzz/net_fuzz.cc index 63cd1ac98..468437b0c 100644 --- a/test/fuzz/net_fuzz.cc +++ b/test/fuzz/net_fuzz.cc @@ -69,14 +69,6 @@ void tud_network_init_cb(void) { // TODO removed later since it is not part of tinyusb stack uint8_t tud_network_mac_address[6] = {0}; -//------------- NCM -------------// - -// callback to client providing optional indication of internal state of network -// driver -void tud_network_link_state_cb(bool state) { - (void)state; - // NoOp. -} -} +} // extern "C" #endif -- cgit v1.3.1 From fca08c939c0d04b9485413166b69f8abac6fb083 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 20 Aug 2023 18:22:07 +0200 Subject: files taken from yapicoprobe --- src/class/net/ncm.h | 106 +++- src/class/net/ncm_device.c | 1281 +++++++++++++++++++++++++++++++------------- src/class/net/net_device.h | 24 +- 3 files changed, 997 insertions(+), 414 deletions(-) diff --git a/src/class/net/ncm.h b/src/class/net/ncm.h index 96ba11fbc..313237747 100644 --- a/src/class/net/ncm.h +++ b/src/class/net/ncm.h @@ -30,10 +30,47 @@ #include "common/tusb_common.h" -#ifdef __cplusplus - extern "C" { + +#ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE + /// must be >> MTU + #define CFG_TUD_NCM_IN_NTB_MAX_SIZE 3200 +#endif +#ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE + /// must be >> MTU + #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE 3200 +#endif + +#ifndef CFG_TUD_NCM_OUT_NTB_N + /// number of ntb buffers for reception side + /// 1 - good performance + /// 2 - up to 30% more performance with iperf with small packets + /// >2 - no performance gain + #define CFG_TUD_NCM_OUT_NTB_N 2 +#endif + +#ifndef CFG_TUD_NCM_IN_NTB_N + /// number of ntb buffers for transmission side + /// 1 - good performance but SystemView shows lost events (on load test) + /// 2 - up to 50% more performance with iperf with small packets, "tud_network_can_xmit: request blocked" + /// happens from time to time with SystemView + /// 3 - "tud_network_can_xmit: request blocked" never happens + /// >2 - no performance gain + #define CFG_TUD_NCM_IN_NTB_N 3 +#endif + +#ifndef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + /// this is for the transmission size for allocation of \a ndp16_datagram_t + #define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 8 +#endif + +#ifndef CFG_TUD_NCM_ALIGNMENT + #define CFG_TUD_NCM_ALIGNMENT 4 +#endif +#if (CFG_TUD_NCM_ALIGNMENT != 4) + #error "CFG_TUD_NCM_ALIGNMENT must be 4, otherwise the headers and start of datagrams have to be aligned (which they are currently not)" #endif + // Table 4.3 Data Class Interface Protocol Codes typedef enum { @@ -62,8 +99,67 @@ typedef enum NCM_SET_CRC_MODE = 0x8A, } ncm_request_code_t; -#ifdef __cplusplus - } -#endif + +#define NTH16_SIGNATURE 0x484D434E +#define NDP16_SIGNATURE_NCM0 0x304D434E +#define NDP16_SIGNATURE_NCM1 0x314D434E + +typedef struct TU_ATTR_PACKED { + uint16_t wLength; + uint16_t bmNtbFormatsSupported; + uint32_t dwNtbInMaxSize; + uint16_t wNdbInDivisor; + uint16_t wNdbInPayloadRemainder; + uint16_t wNdbInAlignment; + uint16_t wReserved; + uint32_t dwNtbOutMaxSize; + uint16_t wNdbOutDivisor; + uint16_t wNdbOutPayloadRemainder; + uint16_t wNdbOutAlignment; + uint16_t wNtbOutMaxDatagrams; +} ntb_parameters_t; + +typedef struct TU_ATTR_PACKED { + uint32_t dwSignature; + uint16_t wHeaderLength; + uint16_t wSequence; + uint16_t wBlockLength; + uint16_t wNdpIndex; +} nth16_t; + +typedef struct TU_ATTR_PACKED { + uint16_t wDatagramIndex; + uint16_t wDatagramLength; +} ndp16_datagram_t; + +typedef struct TU_ATTR_PACKED { + uint32_t dwSignature; + uint16_t wLength; + uint16_t wNextNdpIndex; + //ndp16_datagram_t datagram[]; +} ndp16_t; + +typedef union TU_ATTR_PACKED { + struct { + nth16_t nth; + ndp16_t ndp; + ndp16_datagram_t ndp_datagram[CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + 1]; + }; + uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; +} xmit_ntb_t; + +typedef union TU_ATTR_PACKED { + struct { + nth16_t nth; + // only the header is at a guaranteed position + }; + uint8_t data[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; +} recv_ntb_t; + +struct ncm_notify_t { + tusb_control_request_t header; + uint32_t downlink, uplink; +}; + #endif diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 226c42c4e..f7a236e69 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -1,9 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2020 Jacob Berg Potter - * Copyright (c) 2020 Peter Lawrence - * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2023 Hardy Griech * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,493 +24,1004 @@ * This file is part of the TinyUSB stack. */ +/** + * Small Glossary (from the spec) + * -------------- + * Datagram - A collection of bytes forming a single item of information, passed as a unit from source to destination. + * NCM - Network Control Model + * NDP - NCM Datagram Pointer: NTB structure that delineates Datagrams (typically Ethernet frames) within an NTB + * NTB - NCM Transfer Block: a data structure for efficient USB encapsulation of one or more datagrams + * Each NTB is designed to be a single USB transfer + * NTH - NTB Header: a data structure at the front of each NTB, which provides the information needed to validate + * the NTB and begin decoding + * + * Some explanations + * ----------------- + * - rhport is the USB port of the device, in most cases "0" + * - itf_data_alt if != 0 -> data xmit/recv are allowed (see spec) + * - ep_in IN endpoints take data from the device intended to go in to the host (the device transmits) + * - ep_out OUT endpoints send data out of the host to the device (the device receives) + */ + #include "tusb_option.h" -#if ( CFG_TUD_ENABLED && CFG_TUD_NCM ) +#if ECLIPSE_GUI || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) + +#include +#include +#include #include "device/usbd.h" #include "device/usbd_pvt.h" + #include "net_device.h" +#include "ncm.h" + + +#if !defined(tu_static) || ECLIPSE_GUI + // TinyUSB <=0.15.0 does not know "tu_static" + #define tu_static static +#endif -// Level where CFG_TUSB_DEBUG must be at least for this driver is logged -#ifndef CFG_TUD_NCM_LOG_LEVEL - #define CFG_TUD_NCM_LOG_LEVEL CFG_TUD_LOG_LEVEL +#if 0 + #define DEBUG_OUT(...) printf(__VA_ARGS__) + #define DEBUG_OUT_ENABLED +#else + #define DEBUG_OUT(...) #endif -#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_NCM_LOG_LEVEL, __VA_ARGS__) +#if 0 + #define INFO_OUT(...) printf(__VA_ARGS__) +#else + #define INFO_OUT(...) +#endif + +#if 1 + #define ERROR_OUT(...) printf(__VA_ARGS__) +#else + #define ERROR_OUT(...) +#endif + +// calculate alignment of xmit datagrams within an NTB +#define XMIT_ALIGN_OFFSET(x) ((CFG_TUD_NCM_ALIGNMENT - ((x) & (CFG_TUD_NCM_ALIGNMENT - 1))) & (CFG_TUD_NCM_ALIGNMENT - 1)) + +//----------------------------------------------------------------------------- +// +// Module global things +// +#define XMIT_NTB_N CFG_TUD_NCM_IN_NTB_N +#define RECV_NTB_N CFG_TUD_NCM_OUT_NTB_N + +typedef struct { + // general + uint8_t ep_in; //!< endpoint for outgoing datagrams (naming is a little bit confusing) + uint8_t ep_out; //!< endpoint for incoming datagrams (naming is a little bit confusing) + uint8_t ep_notif; //!< endpoint for notifications + uint8_t itf_num; //!< interface number + uint8_t itf_data_alt; //!< ==0 -> no endpoints, i.e. no network traffic, ==1 -> normal operation with two endpoints (spec, chapter 5.3) + uint8_t rhport; //!< storage of \a rhport because some callbacks are done without it + + // recv handling + recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs + recv_ntb_t *recv_free_ntb[RECV_NTB_N]; //!< free list of recv NTBs + recv_ntb_t *recv_ready_ntb[RECV_NTB_N]; //!< NTBs waiting for transmission to glue logic + recv_ntb_t *recv_tinyusb_ntb; //!< buffer for the running transfer TinyUSB -> driver + recv_ntb_t *recv_glue_ntb; //!< buffer for the running transfer driver -> glue logic + uint16_t recv_glue_ntb_datagram_ndx; //!< index into \a recv_glue_ntb_datagram + + // xmit handling + xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs + xmit_ntb_t *xmit_free_ntb[XMIT_NTB_N]; //!< free list of xmit NTBs + xmit_ntb_t *xmit_ready_ntb[XMIT_NTB_N]; //!< NTBs waiting for transmission to TinyUSB + xmit_ntb_t *xmit_tinyusb_ntb; //!< buffer for the running transfer driver -> TinyUSB + xmit_ntb_t *xmit_glue_ntb; //!< buffer for the running transfer glue logic -> driver + uint16_t xmit_sequence; //!< NTB sequence counter + uint16_t xmit_glue_ntb_datagram_ndx; //!< index into \a xmit_glue_ntb_datagram + + // notification handling + enum { + NOTIFICATION_SPEED, + NOTIFICATION_CONNECTED, + NOTIFICATION_DONE + } notification_xmit_state; //!< state of notification transmission + bool notification_xmit_is_running; //!< notification is currently transmitted +} ncm_interface_t; + -//--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF -//--------------------------------------------------------------------+ +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static ncm_interface_t ncm_interface; -#define NTH16_SIGNATURE 0x484D434E -#define NDP16_SIGNATURE_NCM0 0x304D434E -#define NDP16_SIGNATURE_NCM1 0x314D434E -typedef struct TU_ATTR_PACKED +/** + * This is the NTB parameter structure + * + * \attention + * We are lucky, that byte order is correct + */ +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { + .wLength = sizeof(ntb_parameters_t), + .bmNtbFormatsSupported = 0x01, // 16-bit NTB supported + .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, + .wNdbInDivisor = 4, + .wNdbInPayloadRemainder = 0, + .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, + .wReserved = 0, + .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, + .wNdbOutDivisor = 4, + .wNdbOutPayloadRemainder = 0, + .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, + .wNtbOutMaxDatagrams = 6 // 0=no limit +}; + +// Some confusing remarks about wNtbOutMaxDatagrams... +// ==1 -> SystemView packets/s goes up to 2000 and events are lost during startup +// ==0 -> SystemView runs fine, iperf shows in wireshark a lot of error +// ==6 -> SystemView runs fine, iperf also +// >6 -> iperf starts to show errors +// -> 6 seems to be the best value. Why? Don't know, perhaps only on my system? +// switch \a INFO_OUT on to see interesting values for this. +// +// iperf: for MSS in 100 200 400 800 1200 1450 1500; do iperf -c 192.168.14.1 -e -i 1 -M $MSS -l 8192 -P 1; sleep 2; done +// sysview: SYSTICKS_PER_SEC=35000, IDLE_US=1000, PRINT_MOD=1000 +// + +//----------------------------------------------------------------------------- +// +// everything about notifications +// +tu_static struct ncm_notify_t ncm_notify_connected = { + .header = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = CDC_NOTIF_NETWORK_CONNECTION, + .wValue = 1 /* Connected */, + .wLength = 0, + }, +}; + +tu_static struct ncm_notify_t ncm_notify_speed_change = { + .header = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE, + .wLength = 8, + }, + .downlink = 1000000, + .uplink = 1000000, +}; + + + +static void notification_xmit(uint8_t rhport, bool force_next) +/** + * Transmit next notification to the host (if appropriate). + * Notifications are transferred to the host once during connection setup. + */ { - uint16_t wLength; - uint16_t bmNtbFormatsSupported; - uint32_t dwNtbInMaxSize; - uint16_t wNdbInDivisor; - uint16_t wNdbInPayloadRemainder; - uint16_t wNdbInAlignment; - uint16_t wReserved; - uint32_t dwNtbOutMaxSize; - uint16_t wNdbOutDivisor; - uint16_t wNdbOutPayloadRemainder; - uint16_t wNdbOutAlignment; - uint16_t wNtbOutMaxDatagrams; -} ntb_parameters_t; - -typedef struct TU_ATTR_PACKED + DEBUG_OUT("notification_xmit(%d, %d) - %d %d\n", force_next, rhport, ncm_interface.notification_xmit_state, ncm_interface.notification_xmit_is_running); + + if ( !force_next && ncm_interface.notification_xmit_is_running) { + return; + } + + if (ncm_interface.notification_xmit_state == NOTIFICATION_SPEED) { + DEBUG_OUT(" NOTIFICATION_SPEED\n"); + ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*) &ncm_notify_speed_change, sizeof(ncm_notify_speed_change)); + ncm_interface.notification_xmit_state = NOTIFICATION_CONNECTED; + ncm_interface.notification_xmit_is_running = true; + } + else if (ncm_interface.notification_xmit_state == NOTIFICATION_CONNECTED) { + DEBUG_OUT(" NOTIFICATION_CONNECTED\n"); + ncm_notify_connected.header.wIndex = ncm_interface.itf_num; + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*) &ncm_notify_connected, sizeof(ncm_notify_connected)); + ncm_interface.notification_xmit_state = NOTIFICATION_DONE; + ncm_interface.notification_xmit_is_running = true; + } + else { + DEBUG_OUT(" NOTIFICATION_FINISHED\n"); + } +} // notification_xmit + + +//----------------------------------------------------------------------------- +// +// everything about packet transmission (driver -> TinyUSB) +// + + +static void xmit_put_ntb_into_free_list(xmit_ntb_t *free_ntb) +/** + * Put NTB into the transmitter free list. + */ { - uint32_t dwSignature; - uint16_t wHeaderLength; - uint16_t wSequence; - uint16_t wBlockLength; - uint16_t wNdpIndex; -} nth16_t; - -typedef struct TU_ATTR_PACKED + DEBUG_OUT("xmit_put_ntb_into_free_list() - %p\n", ncm_interface.xmit_tinyusb_ntb); + + if (free_ntb == NULL) { + // can happen due to ZLPs + return; + } + + for (int i = 0; i < XMIT_NTB_N; ++i) { + if (ncm_interface.xmit_free_ntb[i] == NULL) { + ncm_interface.xmit_free_ntb[i] = free_ntb; + return; + } + } + ERROR_OUT("xmit_put_ntb_into_free_list - no entry in free list\n"); // this should not happen +} // xmit_put_ntb_into_free_list + + + +static xmit_ntb_t *xmit_get_free_ntb(void) +/** + * Get an NTB from the free list + */ { - uint16_t wDatagramIndex; - uint16_t wDatagramLength; -} ndp16_datagram_t; + DEBUG_OUT("xmit_get_free_ntb()\n"); + + for (int i = 0; i < XMIT_NTB_N; ++i) { + if (ncm_interface.xmit_free_ntb[i] != NULL) { + xmit_ntb_t *free = ncm_interface.xmit_free_ntb[i]; + ncm_interface.xmit_free_ntb[i] = NULL; + return free; + } + } + return NULL; +} // xmit_get_free_ntb -typedef struct TU_ATTR_PACKED + + +static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) +/** + * Put a filled NTB into the ready list + */ { - uint32_t dwSignature; - uint16_t wLength; - uint16_t wNextNdpIndex; - ndp16_datagram_t datagram[]; -} ndp16_t; - -typedef union TU_ATTR_PACKED { - struct { - nth16_t nth; - ndp16_t ndp; - }; - uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; -} transmit_ntb_t; - -struct ecm_notify_struct + INFO_OUT("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->len); + + for (int i = 0; i < XMIT_NTB_N; ++i) { + if (ncm_interface.xmit_ready_ntb[i] == NULL) { + ncm_interface.xmit_ready_ntb[i] = ready_ntb; + return; + } + } + ERROR_OUT("xmit_put_ntb_into_ready_list: ready list full\n"); // this should not happen +} // xmit_put_ntb_into_ready_list + + + +static xmit_ntb_t *xmit_get_next_ready_ntb(void) +/** + * Get the next NTB from the ready list (and remove it from the list). + * If the ready list is empty, return NULL. + */ { - tusb_control_request_t header; - uint32_t downlink, uplink; -}; + xmit_ntb_t *r = NULL; -typedef struct + r = ncm_interface.xmit_ready_ntb[0]; + memmove(ncm_interface.xmit_ready_ntb + 0, ncm_interface.xmit_ready_ntb + 1, sizeof(ncm_interface.xmit_ready_ntb) - sizeof(ncm_interface.xmit_ready_ntb[0])); + + DEBUG_OUT("recv_get_next_ready_ntb: %p\n", r); + return r; +} // xmit_get_next_ready_ntb + + + +static bool xmit_insert_required_zlp(uint8_t rhport, uint16_t xferred_bytes) +/** + * Transmit a ZLP if required + * + * \note + * Insertion of the ZLPs is a little bit different then described in the spec. + * But the below implementation actually works. Don't know if this is a spec + * or TinyUSB issue. + * + * \pre + * This must be called from netd_xfer_cb() so that ep_in is ready + */ { - uint8_t itf_num; // Index number of Management Interface, +1 for Data Interface - uint8_t itf_data_alt; // Alternate setting of Data Interface. 0 : inactive, 1 : active + DEBUG_OUT("xmit_insert_required_zlp(%d,%d)\n", rhport, xferred_bytes); - uint8_t ep_notif; - uint8_t ep_in; - uint8_t ep_out; + if (xferred_bytes == 0 || xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE != 0) { + return false; + } - const ndp16_t *ndp; - uint8_t num_datagrams, current_datagram_index; + TU_ASSERT(ncm_interface.itf_data_alt == 1, false); + TU_ASSERT( !usbd_edpt_busy(rhport, ncm_interface.ep_in), false); - enum { - REPORT_SPEED, - REPORT_CONNECTED, - REPORT_DONE - } report_state; - bool report_pending; + INFO_OUT("xmit_insert_required_zlp! (%u)\n", (unsigned)xferred_bytes); - uint8_t current_ntb; // Index in transmit_ntb[] that is currently being filled with datagrams - uint8_t datagram_count; // Number of datagrams in transmit_ntb[current_ntb] - uint16_t next_datagram_offset; // Offset in transmit_ntb[current_ntb].data to place the next datagram - uint16_t ntb_in_size; // Maximum size of transmitted (IN to host) NTBs; initially CFG_TUD_NCM_IN_NTB_MAX_SIZE - uint8_t max_datagrams_per_ntb; // Maximum number of datagrams per NTB; initially CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + // start transmission of the ZLP + usbd_edpt_xfer(rhport, ncm_interface.ep_in, NULL, 0); - uint16_t nth_sequence; // Sequence number counter for transmitted NTBs + return true; +} // xmit_insert_required_zlp - bool transferring; -} ncm_interface_t; -//--------------------------------------------------------------------+ -// INTERNAL OBJECT & FUNCTION DECLARATION -//--------------------------------------------------------------------+ - -CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { - .wLength = sizeof(ntb_parameters_t), - .bmNtbFormatsSupported = 0x01, - .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, - .wNdbInDivisor = 4, - .wNdbInPayloadRemainder = 0, - .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, - .wReserved = 0, - .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, - .wNdbOutDivisor = 4, - .wNdbOutPayloadRemainder = 0, - .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, - .wNtbOutMaxDatagrams = 0 -}; +static void xmit_start_if_possible(uint8_t rhport) +/** + * Start transmission if it there is a waiting packet and if can be done from interface side. + */ +{ + DEBUG_OUT("xmit_start_if_possible()\n"); -CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2]; + if (ncm_interface.xmit_tinyusb_ntb != NULL) { + DEBUG_OUT(" !xmit_start_if_possible 1\n"); + return; + } + if (ncm_interface.itf_data_alt != 1) { + ERROR_OUT(" !xmit_start_if_possible 2\n"); + return; + } + if (usbd_edpt_busy(rhport, ncm_interface.ep_in)) { + INFO_OUT(" !xmit_start_if_possible 3\n"); + return; + } -CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t receive_ntb[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; + ncm_interface.xmit_tinyusb_ntb = xmit_get_next_ready_ntb(); + if (ncm_interface.xmit_tinyusb_ntb == NULL) { + if (ncm_interface.xmit_glue_ntb == NULL || ncm_interface.xmit_glue_ntb_datagram_ndx == 0) { + // -> really nothing is waiting + return; + } + ncm_interface.xmit_tinyusb_ntb = ncm_interface.xmit_glue_ntb; + ncm_interface.xmit_glue_ntb = NULL; + } + +#if DEBUG_OUT_ENABLED + { + uint16_t len = ncm_interface.xmit_tinyusb_ntb->ntb.nth.wBlockLength; + DEBUG_OUT(" %d\n", len); + for (int i = 0; i < len; ++i) { + DEBUG_OUT(" %02x", ncm_interface.xmit_tinyusb_ntb->data[i]); + } + DEBUG_OUT("\n"); + } +#endif + + if (ncm_interface.xmit_glue_ntb_datagram_ndx != 1) { + DEBUG_OUT(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->len, ncm_interface.xmit_glue_ntb_datagram_ndx); + } -tu_static ncm_interface_t ncm_interface; + // Kick off an endpoint transfer + usbd_edpt_xfer(0, ncm_interface.ep_in, ncm_interface.xmit_tinyusb_ntb->data, ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength); +} // xmit_start_if_possible -/* - * Set up the NTB state in ncm_interface to be ready to add datagrams. + + +static bool xmit_requested_datagram_fits_into_current_ntb(uint16_t datagram_size) +/** + * check if a new datagram fits into the current NTB */ -static void ncm_prepare_for_tx(void) { - ncm_interface.datagram_count = 0; - // datagrams start after all the headers - ncm_interface.next_datagram_offset = sizeof(nth16_t) + sizeof(ndp16_t) - + ((CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + 1) * sizeof(ndp16_datagram_t)); -} +{ + DEBUG_OUT("xmit_requested_datagram_fits_into_current_ntb(%d) - %p %p\n", datagram_size, ncm_interface.xmit_tinyusb_ntb, ncm_interface.xmit_glue_ntb); -/* - * If not already transmitting, start sending the current NTB to the host and swap buffers - * to start filling the other one with datagrams. + if (ncm_interface.xmit_glue_ntb == NULL) { + return false; + } + if (ncm_interface.xmit_glue_ntb_datagram_ndx >= CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB) { + return false; + } + if (ncm_interface.xmit_glue_ntb->nth.wBlockLength + datagram_size + XMIT_ALIGN_OFFSET(datagram_size) > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + return false; + } + return true; +} // xmit_requested_datagram_fits_into_current_ntb + + + +static bool xmit_setup_next_glue_ntb(void) +/** + * Setup an NTB for the glue logic */ -static void ncm_start_tx(void) { - if (ncm_interface.transferring) { - return; - } - - transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; - size_t ntb_length = ncm_interface.next_datagram_offset; - - // Fill in NTB header - ntb->nth.dwSignature = NTH16_SIGNATURE; - ntb->nth.wHeaderLength = sizeof(nth16_t); - ntb->nth.wSequence = ncm_interface.nth_sequence++; - ntb->nth.wBlockLength = ntb_length; - ntb->nth.wNdpIndex = sizeof(nth16_t); - - // Fill in NDP16 header and terminator - ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; - ntb->ndp.wLength = sizeof(ndp16_t) + (ncm_interface.datagram_count + 1) * sizeof(ndp16_datagram_t); - ntb->ndp.wNextNdpIndex = 0; - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = 0; - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = 0; - - // Kick off an endpoint transfer - usbd_edpt_xfer(0, ncm_interface.ep_in, ntb->data, ntb_length); - ncm_interface.transferring = true; - - // Swap to the other NTB and clear it out - ncm_interface.current_ntb = 1 - ncm_interface.current_ntb; - ncm_prepare_for_tx(); -} - -tu_static struct ecm_notify_struct ncm_notify_connected = { - .header = { - .bmRequestType_bit = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, - .bRequest = CDC_NOTIF_NETWORK_CONNECTION, - .wValue = 1 /* Connected */, - .wLength = 0, - }, -}; + DEBUG_OUT("xmit_setup_next_glue_ntb - %p\n", ncm_interface.xmit_glue_ntb); + + if (ncm_interface.xmit_glue_ntb != NULL) { + // put NTB into waiting list (the new datagram did not fit in) + xmit_put_ntb_into_ready_list(ncm_interface.xmit_glue_ntb); + } + + ncm_interface.xmit_glue_ntb = xmit_get_free_ntb(); // get next buffer (if any) + if (ncm_interface.xmit_glue_ntb == NULL) { + DEBUG_OUT(" xmit_setup_next_glue_ntb - nothing free\n"); // should happen rarely + return false; + } + + ncm_interface.xmit_glue_ntb_datagram_ndx = 0; + + xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; + + // Fill in NTB header + ntb->nth.dwSignature = NTH16_SIGNATURE; + ntb->nth.wHeaderLength = sizeof(ntb->nth); + ntb->nth.wSequence = ncm_interface.xmit_sequence++; + ntb->nth.wBlockLength = sizeof(ntb->nth) + sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); + ntb->nth.wNdpIndex = sizeof(ntb->nth); + + // Fill in NDP16 header and terminator + ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; + ntb->ndp.wLength = sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); + ntb->ndp.wNextNdpIndex = 0; + + memset(ntb->ndp_datagram, 0, sizeof(ntb->ndp_datagram)); + return true; +} // xmit_setup_next_glue_ntb + -tu_static struct ecm_notify_struct ncm_notify_speed_change = +//----------------------------------------------------------------------------- +// +// all the recv_*() stuff (TinyUSB -> driver -> glue logic) +// + + +static recv_ntb_t *recv_get_free_ntb(void) +/** + * Return pointer to an available receive buffer or NULL. + * Returned buffer (if any) has the size \a CFG_TUD_NCM_OUT_NTB_MAX_SIZE. + */ { - .header = { - .bmRequestType_bit = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, - .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE, - .wLength = 8, - }, - .downlink = 10000000, - .uplink = 10000000, -}; + DEBUG_OUT("recv_get_free_ntb()\n"); -void tud_network_recv_renew(void) + for (int i = 0; i < RECV_NTB_N; ++i) { + if (ncm_interface.recv_free_ntb[i] != NULL) { + recv_ntb_t *free = ncm_interface.recv_free_ntb[i]; + ncm_interface.recv_free_ntb[i] = NULL; + return free; + } + } + return NULL; +} // recv_get_free_ntb + + + +static recv_ntb_t *recv_get_next_ready_ntb(void) +/** + * Get the next NTB from the ready list (and remove it from the list). + * If the ready list is empty, return NULL. + */ { - if (!ncm_interface.num_datagrams) - { - usbd_edpt_xfer(0, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); - return; - } + recv_ntb_t *r = NULL; - const ndp16_t *ndp = ncm_interface.ndp; - const int i = ncm_interface.current_datagram_index; - ncm_interface.current_datagram_index++; - ncm_interface.num_datagrams--; + r = ncm_interface.recv_ready_ntb[0]; + memmove(ncm_interface.recv_ready_ntb + 0, ncm_interface.recv_ready_ntb + 1, sizeof(ncm_interface.recv_ready_ntb) - sizeof(ncm_interface.recv_ready_ntb[0])); - tud_network_recv_cb(receive_ntb + ndp->datagram[i].wDatagramIndex, ndp->datagram[i].wDatagramLength); -} + DEBUG_OUT("recv_get_next_ready_ntb: %p\n", r); + return r; +} // recv_get_next_ready_ntb -//--------------------------------------------------------------------+ -// USBD Driver API -//--------------------------------------------------------------------+ -void netd_init(void) + +static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) +/** + * + */ { - tu_memclr(&ncm_interface, sizeof(ncm_interface)); - ncm_interface.ntb_in_size = CFG_TUD_NCM_IN_NTB_MAX_SIZE; - ncm_interface.max_datagrams_per_ntb = CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB; - ncm_prepare_for_tx(); -} + DEBUG_OUT("recv_put_ntb_into_free_list(%p)\n", free_ntb); -void netd_reset(uint8_t rhport) + for (int i = 0; i < RECV_NTB_N; ++i) { + if (ncm_interface.recv_free_ntb[i] == NULL) { + ncm_interface.recv_free_ntb[i] = free_ntb; + return; + } + } + ERROR_OUT("recv_put_ntb_into_free_list - no entry in free list\n"); // this should not happen +} // recv_put_ntb_into_free_list + + + +static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) +/** + * The \a ncm_interface.recv_tinyusb_ntb is filled, + * put this buffer into the waiting list and free the receive logic. + */ { - (void) rhport; + DEBUG_OUT("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->len); + + for (int i = 0; i < RECV_NTB_N; ++i) { + if (ncm_interface.recv_ready_ntb[i] == NULL) { + ncm_interface.recv_ready_ntb[i] = ready_ntb; + return; + } + } + ERROR_OUT("recv_put_ntb_into_ready_list: ready list full\n"); // this should not happen +} // recv_put_ntb_into_ready_list + - netd_init(); -} -uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) +static void recv_try_to_start_new_reception(uint8_t rhport) +/** + * If possible, start a new reception TinyUSB -> driver. + * Return value is actually not of interest. + */ { - // confirm interface hasn't already been allocated - TU_ASSERT(0 == ncm_interface.ep_notif, 0); + DEBUG_OUT("recv_try_to_start_new_reception(%d)\n", rhport); - //------------- Management Interface -------------// - ncm_interface.itf_num = itf_desc->bInterfaceNumber; + if (ncm_interface.itf_data_alt != 1) { + return; + } + if (ncm_interface.recv_tinyusb_ntb != NULL) { + return; + } + if (usbd_edpt_busy(ncm_interface.rhport, ncm_interface.ep_out)) { + return; + } - uint16_t drv_len = sizeof(tusb_desc_interface_t); - uint8_t const * p_desc = tu_desc_next( itf_desc ); + ncm_interface.recv_tinyusb_ntb = recv_get_free_ntb(); + if (ncm_interface.recv_tinyusb_ntb == NULL) { + return; + } - // Communication Functional Descriptors - while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len ) - { - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); - } + // initiate transfer + DEBUG_OUT(" start reception\n"); + bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.recv_tinyusb_ntb->data, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + if ( !r) { + recv_put_ntb_into_free_list(ncm_interface.recv_tinyusb_ntb); + ncm_interface.recv_tinyusb_ntb = NULL; + } +} // recv_try_to_start_new_reception - // notification endpoint (if any) - if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) - { - TU_ASSERT( usbd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), 0 ); - ncm_interface.ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress; - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); - } +static bool recv_validate_datagram(const recv_ntb_t *ntb, uint16_t len) +/** + * Validate incoming datagram. + * \return true if valid + * + * \note + * \a ndp16->wNextNdpIndex != 0 is not supported + */ +{ + const nth16_t *nth16 = &(ntb->nth); - //------------- Data Interface -------------// - // - CDC-NCM data interface has 2 alternate settings - // - 0 : zero endpoints for inactive (default) - // - 1 : IN & OUT endpoints for transfer of NTBs - TU_ASSERT(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0); + DEBUG_OUT("recv_validate_datagram(%p)\n", ntb); - do - { - tusb_desc_interface_t const * data_itf_desc = (tusb_desc_interface_t const *) p_desc; - TU_ASSERT(TUSB_CLASS_CDC_DATA == data_itf_desc->bInterfaceClass, 0); + // + // check header + // + if (nth16->wHeaderLength != sizeof(nth16_t)) + { + ERROR_OUT(" ill nth16 length: %d\n", nth16->wHeaderLength); + return false; + } + if (nth16->dwSignature != NTH16_SIGNATURE) { + ERROR_OUT(" ill signature: 0x%08x\n", (unsigned)nth16->dwSignature); + return false; + } + if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { + ERROR_OUT(" ill min len: %d\n", len); + return false; + } + if (nth16->wBlockLength > len) { + ERROR_OUT(" ill block length: %d > %d\n", nth16->wBlockLength, len); + return false; + } + if (nth16->wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + ERROR_OUT(" ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + return false; + } + if (nth16->wNdpIndex < sizeof(nth16) || nth16->wNdpIndex > len - (sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t))) { + ERROR_OUT(" ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); + return false; + } - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); - } while((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && (drv_len <= max_len)); + // + // check (first) NDP(16) + // + const ndp16_t *ndp16 = (ndp16_t *)(ntb->data + nth16->wNdpIndex); - // Pair of endpoints - TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc), 0); + if (ndp16->wLength < sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { + ERROR_OUT(" ill ndp16 length: %d\n", ndp16->wLength); + return false; + } + if (ndp16->dwSignature != NDP16_SIGNATURE_NCM0 && ndp16->dwSignature != NDP16_SIGNATURE_NCM1) { + ERROR_OUT(" ill signature: 0x%08x\n", (unsigned)ndp16->dwSignature); + return false; + } + if (ndp16->wNextNdpIndex != 0) { + ERROR_OUT(" cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); + return false; + } - TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in) ); + const ndp16_datagram_t *ndp16_datagram = (ndp16_datagram_t *)(ntb->data + nth16->wNdpIndex + sizeof(ndp16_t)); + int ndx = 0; + int max_ndx = (ndp16->wLength - sizeof(ndp16_t)) / sizeof(ndp16_datagram_t); - drv_len += 2*sizeof(tusb_desc_endpoint_t); + if (max_ndx > 2) { + // number of datagrams in NTB > 1 + INFO_OUT("<< %d (%d)\n", max_ndx - 1, ntb->len); + } + if (ndp16_datagram[max_ndx-1].wDatagramIndex != 0 || ndp16_datagram[max_ndx-1].wDatagramLength != 0) { + INFO_OUT(" max_ndx != 0\n"); + return false; + } + while (ndp16_datagram[ndx].wDatagramIndex != 0 && ndp16_datagram[ndx].wDatagramLength != 0) { + DEBUG_OUT(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); + if (ndp16_datagram[ndx].wDatagramIndex > len) { + ERROR_OUT(" ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); + return false; + } + if (ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength > len) { + ERROR_OUT(" ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); + return false; + } + ++ndx; + } + + for (int i = 0; i < len; ++i) { + DEBUG_OUT(" %02x", ntb->data[i]); + } + DEBUG_OUT("\n"); + + // -> ntb contains a valid packet structure + // ok... I did not check for garbage within the datagram indices... + return true; +} // recv_validate_datagram - return drv_len; -} -static void ncm_report(void) -{ - uint8_t const rhport = 0; - if (ncm_interface.report_state == REPORT_SPEED) { - ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; - usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_speed_change, sizeof(ncm_notify_speed_change)); - ncm_interface.report_state = REPORT_CONNECTED; - ncm_interface.report_pending = true; - } else if (ncm_interface.report_state == REPORT_CONNECTED) { - ncm_notify_connected.header.wIndex = ncm_interface.itf_num; - usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_connected, sizeof(ncm_notify_connected)); - ncm_interface.report_state = REPORT_DONE; - ncm_interface.report_pending = true; - } -} - -TU_ATTR_WEAK void tud_network_link_state_cb(bool state) -{ - (void)state; -} -// Handle class control request -// return false to stall control endpoint (e.g unsupported request) -bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +static void recv_transfer_datagram_to_glue_logic(void) +/** + * Transfer the next (pending) datagram to the glue logic and return receive buffer if empty. + */ { - if ( stage != CONTROL_STAGE_SETUP ) return true; - - switch ( request->bmRequestType_bit.type ) - { - case TUSB_REQ_TYPE_STANDARD: - switch ( request->bRequest ) - { - case TUSB_REQ_GET_INTERFACE: - { - uint8_t const req_itfnum = (uint8_t) request->wIndex; - TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum); - - tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); + DEBUG_OUT("recv_transfer_datagram_to_glue_logic()\n"); + + if (ncm_interface.recv_glue_ntb == NULL) { + ncm_interface.recv_glue_ntb = recv_get_next_ready_ntb(); + DEBUG_OUT(" new buffer for glue logic: %p\n", ncm_interface.recv_glue_ntb); + ncm_interface.recv_glue_ntb_datagram_ndx = 0; + } + + if (ncm_interface.recv_glue_ntb != NULL) { + const ndp16_datagram_t *ndp16_datagram = (ndp16_datagram_t *)(ncm_interface.recv_glue_ntb->data + + ncm_interface.recv_glue_ntb->nth.wNdpIndex + + sizeof(ndp16_t)); + + if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex == 0) { + ERROR_OUT(" SOMETHING WENT WRONG 1\n"); } - break; - - case TUSB_REQ_SET_INTERFACE: - { - uint8_t const req_itfnum = (uint8_t) request->wIndex; - uint8_t const req_alt = (uint8_t) request->wValue; - - // Only valid for Data Interface with Alternate is either 0 or 1 - TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum && req_alt < 2); - - if (req_alt != ncm_interface.itf_data_alt) { - ncm_interface.itf_data_alt = req_alt; - - if (ncm_interface.itf_data_alt) { - if (!usbd_edpt_busy(rhport, ncm_interface.ep_out)) { - tud_network_recv_renew(); // prepare for incoming datagrams - } - if (!ncm_interface.report_pending) { - ncm_report(); - } + else if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength == 0) { + ERROR_OUT(" SOMETHING WENT WRONG 2\n"); + } + else { + uint16_t datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex; + uint16_t datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength; + + DEBUG_OUT(" recv[%d] - %d %d\n", ncm_interface.recv_glue_ntb_datagram_ndx, datagramIndex, datagramLength); + if (tud_network_recv_cb(ncm_interface.recv_glue_ntb->data + datagramIndex, datagramLength)) { + // + // send datagram successfully to glue logic + // + DEBUG_OUT(" OK\n"); + datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramIndex; + datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramLength; + + if (datagramIndex != 0 && datagramLength != 0) { + // -> next datagram + ++ncm_interface.recv_glue_ntb_datagram_ndx; + } + else { + // end of datagrams reached + recv_put_ntb_into_free_list(ncm_interface.recv_glue_ntb); + ncm_interface.recv_glue_ntb = NULL; + } } + } + } +} // recv_transfer_datagram_to_glue_logic - tud_network_link_state_cb(ncm_interface.itf_data_alt); - } - tud_control_status(rhport, request); - } - break; +//----------------------------------------------------------------------------- +// +// all the tud_network_*() stuff (glue logic -> driver) +// + + +bool tud_network_can_xmit(uint16_t size) +/** + * Check if the glue logic is allowed to call tud_network_xmit(). + * This function also fetches a next buffer if required, so that tud_network_xmit() is ready for copy + * and transmission operation. + */ +{ + DEBUG_OUT("tud_network_can_xmit(%d)\n", size); + + TU_ASSERT(size <= CFG_TUD_NCM_OUT_NTB_MAX_SIZE - (sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)), false); + + if (xmit_requested_datagram_fits_into_current_ntb(size) || xmit_setup_next_glue_ntb()) { + // -> everything is fine + return true; + } + xmit_start_if_possible(ncm_interface.rhport); + ERROR_OUT(" tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) + return false; +} // tud_network_can_xmit - // unsupported request - default: return false; - } - break; - case TUSB_REQ_TYPE_CLASS: - TU_VERIFY (ncm_interface.itf_num == request->wIndex); - if (NCM_GET_NTB_PARAMETERS == request->bRequest) - { - tud_control_xfer(rhport, request, (void*)(uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); - } +void tud_network_xmit(void *ref, uint16_t arg) +/** + * Put a datagram into a waiting NTB. + * If currently no transmission is started, then initiate transmission. + */ +{ + DEBUG_OUT("tud_network_xmit(%p, %d)\n", ref, arg); + + if (ncm_interface.xmit_glue_ntb == NULL) { + ERROR_OUT("tud_network_xmit: no buffer\n"); // must not happen (really) + return; + } + + xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; + + // copy new datagram to the end of the current NTB + uint16_t size = tud_network_xmit_cb(ntb->data + ntb->nth.wBlockLength, ref, arg); + + // correct NTB internals + ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramIndex = ntb->nth.wBlockLength; + ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramLength = size; + ncm_interface.xmit_glue_ntb_datagram_ndx += 1; - break; + ntb->nth.wBlockLength += size + XMIT_ALIGN_OFFSET(size); - // unsupported request - default: return false; - } + if (ntb->nth.wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + ERROR_OUT("tud_network_xmit: buffer overflow\n"); // must not happen (really) + return; + } + + xmit_start_if_possible(ncm_interface.rhport); +} // tud_network_xmit - return true; -} -static void handle_incoming_datagram(uint32_t len) + +void tud_network_recv_renew(void) +/** + * Keep the receive logic busy and transfer pending packets to the glue logic. + */ { - uint32_t size = len; + DEBUG_OUT("tud_network_recv_renew()\n"); - if (len == 0) { - return; - } + recv_transfer_datagram_to_glue_logic(); + recv_try_to_start_new_reception(ncm_interface.rhport); +} // tud_network_recv_renew - TU_ASSERT(size >= sizeof(nth16_t), ); - const nth16_t *hdr = (const nth16_t *)receive_ntb; - TU_ASSERT(hdr->dwSignature == NTH16_SIGNATURE, ); - TU_ASSERT(hdr->wNdpIndex >= sizeof(nth16_t) && (hdr->wNdpIndex + sizeof(ndp16_t)) <= len, ); - const ndp16_t *ndp = (const ndp16_t *)(receive_ntb + hdr->wNdpIndex); - TU_ASSERT(ndp->dwSignature == NDP16_SIGNATURE_NCM0 || ndp->dwSignature == NDP16_SIGNATURE_NCM1, ); - TU_ASSERT(hdr->wNdpIndex + ndp->wLength <= len, ); +void tud_network_recv_renew_r(uint8_t rhport) +/** + * Same as tud_network_recv_renew() but knows \a rhport + */ +{ + DEBUG_OUT("tud_network_recv_renew_r(%d)\n", rhport); - int num_datagrams = (ndp->wLength - 12) / 4; - ncm_interface.current_datagram_index = 0; - ncm_interface.num_datagrams = 0; - ncm_interface.ndp = ndp; - for (int i = 0; i < num_datagrams && ndp->datagram[i].wDatagramIndex && ndp->datagram[i].wDatagramLength; i++) - { - ncm_interface.num_datagrams++; - } + ncm_interface.rhport = rhport; + tud_network_recv_renew(); +} // tud_network_recv_renew - tud_network_recv_renew(); -} -bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +//----------------------------------------------------------------------------- +// +// all the netd_*() stuff (interface TinyUSB -> driver) +// +void netd_init(void) +/** + * Initialize the driver data structures. + * Might be called several times. + */ { - (void) rhport; - (void) result; + DEBUG_OUT("netd_init()\n"); - /* new datagram receive_ntb */ - if (ep_addr == ncm_interface.ep_out ) - { - handle_incoming_datagram(xferred_bytes); - } + memset( &ncm_interface, 0, sizeof(ncm_interface)); - /* data transmission finished */ - if (ep_addr == ncm_interface.ep_in ) - { - if (ncm_interface.transferring) { - ncm_interface.transferring = false; + for (int i = 0; i < XMIT_NTB_N; ++i) { + ncm_interface.xmit_free_ntb[i] = ncm_interface.xmit_ntb + i; } + for (int i = 0; i < RECV_NTB_N; ++i) { + ncm_interface.recv_free_ntb[i] = ncm_interface.recv_ntb + i; + } +} // netd_init + - // If there are datagrams queued up that we tried to send while this NTB was being emitted, send them now - if (ncm_interface.datagram_count && ncm_interface.itf_data_alt == 1) { - ncm_start_tx(); + +void netd_reset(uint8_t rhport) +/** + * Resets the port. + * In this driver this is the same as netd_init() + */ +{ + DEBUG_OUT("netd_reset(%d)\n", rhport); + + netd_init(); +} // netd_reset + + + +uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) +/** + * Open the USB interface. + * - parse the USB descriptor \a TUD_CDC_NCM_DESCRIPTOR for itfnum and endpoints + * - a specific order of elements in the descriptor is tested. + * + * \note + * Actually all of the information could be read directly from \a itf_desc, because the + * structure and the values are well known. But we do it this way. + * + * \post + * - \a itf_num set + * - \a ep_notif, \a ep_in and \a ep_out are set + * - USB interface is open + */ +{ + DEBUG_OUT("netd_open(%d,%p,%d)\n", rhport, itf_desc, max_len); + + TU_ASSERT(ncm_interface.ep_notif == 0, 0); // assure that the interface is only opened once + + ncm_interface.itf_num = itf_desc->bInterfaceNumber; // management interface + + // + // skip the two first entries and the following TUSB_DESC_CS_INTERFACE entries + // + uint16_t drv_len = sizeof(tusb_desc_interface_t); + uint8_t const *p_desc = tu_desc_next(itf_desc); + while (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && drv_len <= max_len) { + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); } - } - if (ep_addr == ncm_interface.ep_notif ) - { - ncm_interface.report_pending = false; - ncm_report(); - } + // + // get notification endpoint + // + TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 0); + TU_ASSERT(usbd_edpt_open(rhport, (tusb_desc_endpoint_t const* ) p_desc), 0); + ncm_interface.ep_notif = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress; + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); - return true; -} + // + // skip the following TUSB_DESC_INTERFACE entries (which must be TUSB_CLASS_CDC_DATA) + // + while (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && drv_len <= max_len) { + tusb_desc_interface_t const *data_itf_desc = (tusb_desc_interface_t const*)p_desc; + TU_ASSERT(data_itf_desc->bInterfaceClass == TUSB_CLASS_CDC_DATA, 0); -// poll network driver for its ability to accept another packet to transmit -bool tud_network_can_xmit(uint16_t size) + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + // + // a TUSB_DESC_ENDPOINT (actually two) must follow, open these endpoints + // + TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 0); + TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in)); + drv_len += 2 * sizeof(tusb_desc_endpoint_t); + + return drv_len; +} // netd_open + + + +bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +/** + * Handle TinyUSB requests to process transfer events. + */ { - TU_VERIFY(ncm_interface.itf_data_alt == 1); + DEBUG_OUT("netd_xfer_cb(%d,%d,%d,%u)\n", rhport, ep_addr, result, (unsigned)xferred_bytes); + + if (ep_addr == ncm_interface.ep_out) { + // + // new NTB received + // - make the NTB valid + // - if ready transfer datagrams to the glue logic for further processing + // - if there is a free receive buffer, initiate reception + // + DEBUG_OUT(" EP_OUT %d %d %d %u\n", rhport, ep_addr, result, (unsigned)xferred_bytes); + if ( !recv_validate_datagram( ncm_interface.recv_tinyusb_ntb, xferred_bytes)) { + // verification failed: ignore NTB and return it to free + ERROR_OUT(" VALIDATION FAILED. WHAT CAN WE DO IN THIS CASE?\n"); + } + else { + // packet ok -> put it into ready list + recv_put_ntb_into_ready_list(ncm_interface.recv_tinyusb_ntb); + } + ncm_interface.recv_tinyusb_ntb = NULL; + tud_network_recv_renew_r(rhport); + } + else if (ep_addr == ncm_interface.ep_in) { + // + // transmission of an NTB finished + // - free the transmitted NTB buffer + // - insert ZLPs when necessary + // - if there is another transmit NTB waiting, try to start transmission + // + DEBUG_OUT(" EP_IN %d %u\n", ncm_interface.itf_data_alt, (unsigned)xferred_bytes); + xmit_put_ntb_into_free_list(ncm_interface.xmit_tinyusb_ntb); + ncm_interface.xmit_tinyusb_ntb = NULL; + if ( !xmit_insert_required_zlp(rhport, xferred_bytes)) { + xmit_start_if_possible(rhport); + } + } + else if (ep_addr == ncm_interface.ep_notif) { + // + // next transfer on notification channel + // + DEBUG_OUT(" EP_NOTIF\n"); + notification_xmit(rhport, true); + } - if (ncm_interface.datagram_count >= ncm_interface.max_datagrams_per_ntb) { - TU_LOG_DRV("NTB full [by count]\r\n"); - return false; - } + return true; +} // netd_xfer_cb - size_t next_datagram_offset = ncm_interface.next_datagram_offset; - if (next_datagram_offset + size > ncm_interface.ntb_in_size) { - TU_LOG_DRV("ntb full [by size]\r\n"); - return false; - } - return true; -} -void tud_network_xmit(void *ref, uint16_t arg) +bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) +/** + * Respond to TinyUSB control requests. + * At startup transmission of notification packets are done here. + */ { - transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; - size_t next_datagram_offset = ncm_interface.next_datagram_offset; + DEBUG_OUT("netd_control_xfer_cb(%d, %d, %p)\n", rhport, stage, request); - uint16_t size = tud_network_xmit_cb(ntb->data + next_datagram_offset, ref, arg); + if (stage != CONTROL_STAGE_SETUP) { + return true; + } - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = ncm_interface.next_datagram_offset; - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = size; + switch (request->bmRequestType_bit.type) { + case TUSB_REQ_TYPE_STANDARD: + switch (request->bRequest) { + case TUSB_REQ_GET_INTERFACE: { + TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex, false); + + DEBUG_OUT(" TUSB_REQ_GET_INTERFACE - %d\n", ncm_interface.itf_data_alt); + tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); + } + break; + + case TUSB_REQ_SET_INTERFACE: { + TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex && request->wValue < 2, false); + + ncm_interface.itf_data_alt = request->wValue; + DEBUG_OUT(" TUSB_REQ_SET_INTERFACE - %d %d %d\n", ncm_interface.itf_data_alt, request->wIndex, ncm_interface.itf_num); + + if (ncm_interface.itf_data_alt == 1) { + tud_network_recv_renew_r(rhport); + notification_xmit(rhport, false); + } + tud_control_status(rhport, request); + } + break; + + // unsupported request + default: + return false; + } + break; - ncm_interface.datagram_count++; - next_datagram_offset += size; + case TUSB_REQ_TYPE_CLASS: + TU_VERIFY(ncm_interface.itf_num == request->wIndex, false); - // round up so the next datagram is aligned correctly - next_datagram_offset += (CFG_TUD_NCM_ALIGNMENT - 1); - next_datagram_offset -= (next_datagram_offset % CFG_TUD_NCM_ALIGNMENT); + DEBUG_OUT(" TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); - ncm_interface.next_datagram_offset = next_datagram_offset; + if (request->bRequest == NCM_GET_NTB_PARAMETERS) { + // transfer NTB parameters to host. + // TODO can one assume, that tud_control_xfer() succeeds? + DEBUG_OUT(" NCM_GET_NTB_PARAMETERS\n"); + tud_control_xfer(rhport, request, (void*) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); + } + break; - ncm_start_tx(); -} + // unsupported request + default: + return false ; + } -#endif + return true; +} // netd_control_xfer_cb + +#endif // ECLIPSE_GUI || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h index 399916355..111c822fb 100644 --- a/src/class/net/net_device.h +++ b/src/class/net/net_device.h @@ -28,14 +28,13 @@ #ifndef _TUSB_NET_DEVICE_H_ #define _TUSB_NET_DEVICE_H_ +#include #include "class/cdc/cdc.h" #if CFG_TUD_ECM_RNDIS && CFG_TUD_NCM #error "Cannot enable both ECM_RNDIS and NCM network drivers" #endif -#include "ncm.h" - /* declared here, NOT in usb_descriptors.c, so that the driver can intelligently ZLP as needed */ #define CFG_TUD_NET_ENDPOINT_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) @@ -44,21 +43,6 @@ #define CFG_TUD_NET_MTU 1514 #endif -#ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE -#define CFG_TUD_NCM_IN_NTB_MAX_SIZE 3200 -#endif - -#ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE -#define CFG_TUD_NCM_OUT_NTB_MAX_SIZE 3200 -#endif - -#ifndef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB -#define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 8 -#endif - -#ifndef CFG_TUD_NCM_ALIGNMENT -#define CFG_TUD_NCM_ALIGNMENT 4 -#endif #ifdef __cplusplus extern "C" { @@ -92,12 +76,6 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg); // client must provide this: initialize any network state back to the beginning void tud_network_init_cb(void); -// client must provide this: 48-bit MAC address -// TODO removed later since it is not part of tinyusb stack -extern uint8_t tud_network_mac_address[6]; - -//------------- NCM -------------// - // callback to client providing optional indication of internal state of network driver void tud_network_link_state_cb(bool state); -- cgit v1.3.1 From d5da303f450ce0e1004121af4a40a512371e9353 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 20 Aug 2023 18:22:07 +0200 Subject: moved some declarations --- src/class/net/ncm.h | 7 ------- src/class/net/net_device.h | 11 +++++++++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/class/net/ncm.h b/src/class/net/ncm.h index 313237747..c768192a5 100644 --- a/src/class/net/ncm.h +++ b/src/class/net/ncm.h @@ -71,13 +71,6 @@ #endif -// Table 4.3 Data Class Interface Protocol Codes -typedef enum -{ - NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK = 0x01 -} ncm_data_interface_protocol_code_t; - - // Table 6.2 Class-Specific Request Codes for Network Control Model subclass typedef enum { diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h index 111c822fb..3342dac3d 100644 --- a/src/class/net/net_device.h +++ b/src/class/net/net_device.h @@ -44,6 +44,13 @@ #endif +// Table 4.3 Data Class Interface Protocol Codes +typedef enum +{ + NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK = 0x01 +} ncm_data_interface_protocol_code_t; + + #ifdef __cplusplus extern "C" { #endif @@ -76,6 +83,10 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg); // client must provide this: initialize any network state back to the beginning void tud_network_init_cb(void); +// client must provide this: 48-bit MAC address +// TODO removed later since it is not part of tinyusb stack +extern uint8_t tud_network_mac_address[6]; + // callback to client providing optional indication of internal state of network driver void tud_network_link_state_cb(bool state); -- cgit v1.3.1 From e4c18c101cf5dc78f6bd1034aae7f0f7e22b7e47 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 20 Aug 2023 18:22:07 +0200 Subject: Copyright --- src/class/net/ncm_device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index f7a236e69..28066b6af 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2023 Hardy Griech + * Copyright (c) 2019 Ha Thach (tinyusb.org) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal -- cgit v1.3.1 From 28107326da6cbc462bf6644f1f6edd5d0bcb43b8 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 20 Aug 2023 18:22:07 +0200 Subject: bug fix recv/xmit_get_next_ready_ntb() --- src/class/net/ncm_device.c | 58 ++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 28066b6af..65543fcab 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -254,7 +254,7 @@ static void xmit_put_ntb_into_free_list(xmit_ntb_t *free_ntb) return; } } - ERROR_OUT("xmit_put_ntb_into_free_list - no entry in free list\n"); // this should not happen + ERROR_OUT("(EE) xmit_put_ntb_into_free_list - no entry in free list\n"); // this should not happen } // xmit_put_ntb_into_free_list @@ -283,7 +283,7 @@ static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) * Put a filled NTB into the ready list */ { - INFO_OUT("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->len); + INFO_OUT("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); for (int i = 0; i < XMIT_NTB_N; ++i) { if (ncm_interface.xmit_ready_ntb[i] == NULL) { @@ -291,7 +291,7 @@ static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) return; } } - ERROR_OUT("xmit_put_ntb_into_ready_list: ready list full\n"); // this should not happen + ERROR_OUT("(EE) xmit_put_ntb_into_ready_list: ready list full\n"); // this should not happen } // xmit_put_ntb_into_ready_list @@ -306,6 +306,7 @@ static xmit_ntb_t *xmit_get_next_ready_ntb(void) r = ncm_interface.xmit_ready_ntb[0]; memmove(ncm_interface.xmit_ready_ntb + 0, ncm_interface.xmit_ready_ntb + 1, sizeof(ncm_interface.xmit_ready_ntb) - sizeof(ncm_interface.xmit_ready_ntb[0])); + ncm_interface.xmit_ready_ntb[XMIT_NTB_N - 1] = NULL; DEBUG_OUT("recv_get_next_ready_ntb: %p\n", r); return r; @@ -357,7 +358,7 @@ static void xmit_start_if_possible(uint8_t rhport) return; } if (ncm_interface.itf_data_alt != 1) { - ERROR_OUT(" !xmit_start_if_possible 2\n"); + ERROR_OUT("(II) !xmit_start_if_possible 2\n"); return; } if (usbd_edpt_busy(rhport, ncm_interface.ep_in)) { @@ -375,9 +376,9 @@ static void xmit_start_if_possible(uint8_t rhport) ncm_interface.xmit_glue_ntb = NULL; } -#if DEBUG_OUT_ENABLED +#ifdef DEBUG_OUT_ENABLED { - uint16_t len = ncm_interface.xmit_tinyusb_ntb->ntb.nth.wBlockLength; + uint16_t len = ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength; DEBUG_OUT(" %d\n", len); for (int i = 0; i < len; ++i) { DEBUG_OUT(" %02x", ncm_interface.xmit_tinyusb_ntb->data[i]); @@ -387,7 +388,7 @@ static void xmit_start_if_possible(uint8_t rhport) #endif if (ncm_interface.xmit_glue_ntb_datagram_ndx != 1) { - DEBUG_OUT(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->len, ncm_interface.xmit_glue_ntb_datagram_ndx); + DEBUG_OUT(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength, ncm_interface.xmit_glue_ntb_datagram_ndx); } // Kick off an endpoint transfer @@ -492,6 +493,7 @@ static recv_ntb_t *recv_get_next_ready_ntb(void) r = ncm_interface.recv_ready_ntb[0]; memmove(ncm_interface.recv_ready_ntb + 0, ncm_interface.recv_ready_ntb + 1, sizeof(ncm_interface.recv_ready_ntb) - sizeof(ncm_interface.recv_ready_ntb[0])); + ncm_interface.recv_ready_ntb[RECV_NTB_N - 1] = NULL; DEBUG_OUT("recv_get_next_ready_ntb: %p\n", r); return r; @@ -512,7 +514,7 @@ static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) return; } } - ERROR_OUT("recv_put_ntb_into_free_list - no entry in free list\n"); // this should not happen + ERROR_OUT("(EE) recv_put_ntb_into_free_list - no entry in free list\n"); // this should not happen } // recv_put_ntb_into_free_list @@ -523,7 +525,7 @@ static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) * put this buffer into the waiting list and free the receive logic. */ { - DEBUG_OUT("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->len); + DEBUG_OUT("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); for (int i = 0; i < RECV_NTB_N; ++i) { if (ncm_interface.recv_ready_ntb[i] == NULL) { @@ -531,7 +533,7 @@ static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) return; } } - ERROR_OUT("recv_put_ntb_into_ready_list: ready list full\n"); // this should not happen + ERROR_OUT("(EE) recv_put_ntb_into_ready_list: ready list full\n"); // this should not happen } // recv_put_ntb_into_ready_list @@ -588,27 +590,27 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint16_t len) // if (nth16->wHeaderLength != sizeof(nth16_t)) { - ERROR_OUT(" ill nth16 length: %d\n", nth16->wHeaderLength); + ERROR_OUT("(EE) ill nth16 length: %d\n", nth16->wHeaderLength); return false; } if (nth16->dwSignature != NTH16_SIGNATURE) { - ERROR_OUT(" ill signature: 0x%08x\n", (unsigned)nth16->dwSignature); + ERROR_OUT("(EE) ill signature: 0x%08x\n", (unsigned)nth16->dwSignature); return false; } if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - ERROR_OUT(" ill min len: %d\n", len); + ERROR_OUT("(EE) ill min len: %d\n", len); return false; } if (nth16->wBlockLength > len) { - ERROR_OUT(" ill block length: %d > %d\n", nth16->wBlockLength, len); + ERROR_OUT("(EE) ill block length: %d > %d\n", nth16->wBlockLength, len); return false; } if (nth16->wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - ERROR_OUT(" ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + ERROR_OUT("(EE) ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); return false; } if (nth16->wNdpIndex < sizeof(nth16) || nth16->wNdpIndex > len - (sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t))) { - ERROR_OUT(" ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); + ERROR_OUT("(EE) ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); return false; } @@ -618,15 +620,15 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint16_t len) const ndp16_t *ndp16 = (ndp16_t *)(ntb->data + nth16->wNdpIndex); if (ndp16->wLength < sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - ERROR_OUT(" ill ndp16 length: %d\n", ndp16->wLength); + ERROR_OUT("(EE) ill ndp16 length: %d\n", ndp16->wLength); return false; } if (ndp16->dwSignature != NDP16_SIGNATURE_NCM0 && ndp16->dwSignature != NDP16_SIGNATURE_NCM1) { - ERROR_OUT(" ill signature: 0x%08x\n", (unsigned)ndp16->dwSignature); + ERROR_OUT("(EE) ill signature: 0x%08x\n", (unsigned)ndp16->dwSignature); return false; } if (ndp16->wNextNdpIndex != 0) { - ERROR_OUT(" cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); + ERROR_OUT("(EE) cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); return false; } @@ -636,7 +638,7 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint16_t len) if (max_ndx > 2) { // number of datagrams in NTB > 1 - INFO_OUT("<< %d (%d)\n", max_ndx - 1, ntb->len); + INFO_OUT("<< %d (%d)\n", max_ndx - 1, ntb->nth.wBlockLength); } if (ndp16_datagram[max_ndx-1].wDatagramIndex != 0 || ndp16_datagram[max_ndx-1].wDatagramLength != 0) { INFO_OUT(" max_ndx != 0\n"); @@ -645,11 +647,11 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint16_t len) while (ndp16_datagram[ndx].wDatagramIndex != 0 && ndp16_datagram[ndx].wDatagramLength != 0) { DEBUG_OUT(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); if (ndp16_datagram[ndx].wDatagramIndex > len) { - ERROR_OUT(" ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); + ERROR_OUT("(EE) ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); return false; } if (ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength > len) { - ERROR_OUT(" ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); + ERROR_OUT("(EE) ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); return false; } ++ndx; @@ -686,10 +688,10 @@ static void recv_transfer_datagram_to_glue_logic(void) + sizeof(ndp16_t)); if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex == 0) { - ERROR_OUT(" SOMETHING WENT WRONG 1\n"); + ERROR_OUT("(EE) SOMETHING WENT WRONG 1\n"); } else if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength == 0) { - ERROR_OUT(" SOMETHING WENT WRONG 2\n"); + ERROR_OUT("(EE) SOMETHING WENT WRONG 2\n"); } else { uint16_t datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex; @@ -741,7 +743,7 @@ bool tud_network_can_xmit(uint16_t size) return true; } xmit_start_if_possible(ncm_interface.rhport); - ERROR_OUT(" tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) + ERROR_OUT("(II) tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) return false; } // tud_network_can_xmit @@ -756,7 +758,7 @@ void tud_network_xmit(void *ref, uint16_t arg) DEBUG_OUT("tud_network_xmit(%p, %d)\n", ref, arg); if (ncm_interface.xmit_glue_ntb == NULL) { - ERROR_OUT("tud_network_xmit: no buffer\n"); // must not happen (really) + ERROR_OUT("(EE) tud_network_xmit: no buffer\n"); // must not happen (really) return; } @@ -773,7 +775,7 @@ void tud_network_xmit(void *ref, uint16_t arg) ntb->nth.wBlockLength += size + XMIT_ALIGN_OFFSET(size); if (ntb->nth.wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - ERROR_OUT("tud_network_xmit: buffer overflow\n"); // must not happen (really) + ERROR_OUT("(II) tud_network_xmit: buffer overflow\n"); // must not happen (really) return; } @@ -925,7 +927,7 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ DEBUG_OUT(" EP_OUT %d %d %d %u\n", rhport, ep_addr, result, (unsigned)xferred_bytes); if ( !recv_validate_datagram( ncm_interface.recv_tinyusb_ntb, xferred_bytes)) { // verification failed: ignore NTB and return it to free - ERROR_OUT(" VALIDATION FAILED. WHAT CAN WE DO IN THIS CASE?\n"); + ERROR_OUT("(EE) VALIDATION FAILED. WHAT CAN WE DO IN THIS CASE?\n"); } else { // packet ok -> put it into ready list -- cgit v1.3.1 From 2c1addff4f853586c8d9590e3f93d79fc7c6e250 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 20 Aug 2023 18:27:06 +0200 Subject: defined(ECLIPSE_GUI) --- src/class/net/ncm_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 65543fcab..1c6f888cd 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -46,7 +46,7 @@ #include "tusb_option.h" -#if ECLIPSE_GUI || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) +#if defined(ECLIPSE_GUI) || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) #include #include -- cgit v1.3.1 From 1dd9fa3f307e6f3a847619d587529ea17608c1a3 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 31 Aug 2023 20:24:56 +0200 Subject: code review: changed to TinyUSB log system --- src/class/net/ncm_device.c | 205 +++++++++++++++++++++------------------------ 1 file changed, 96 insertions(+), 109 deletions(-) diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 1c6f888cd..d0832cf73 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -59,30 +59,11 @@ #include "ncm.h" -#if !defined(tu_static) || ECLIPSE_GUI +#if !defined(tu_static) || defined(ECLIPSE_GUI) // TinyUSB <=0.15.0 does not know "tu_static" #define tu_static static #endif -#if 0 - #define DEBUG_OUT(...) printf(__VA_ARGS__) - #define DEBUG_OUT_ENABLED -#else - #define DEBUG_OUT(...) -#endif - -#if 0 - #define INFO_OUT(...) printf(__VA_ARGS__) -#else - #define INFO_OUT(...) -#endif - -#if 1 - #define ERROR_OUT(...) printf(__VA_ARGS__) -#else - #define ERROR_OUT(...) -#endif - // calculate alignment of xmit datagrams within an NTB #define XMIT_ALIGN_OFFSET(x) ((CFG_TUD_NCM_ALIGNMENT - ((x) & (CFG_TUD_NCM_ALIGNMENT - 1))) & (CFG_TUD_NCM_ALIGNMENT - 1)) @@ -103,7 +84,7 @@ typedef struct { uint8_t rhport; //!< storage of \a rhport because some callbacks are done without it // recv handling - recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs + CFG_TUSB_MEM_ALIGN recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs recv_ntb_t *recv_free_ntb[RECV_NTB_N]; //!< free list of recv NTBs recv_ntb_t *recv_ready_ntb[RECV_NTB_N]; //!< NTBs waiting for transmission to glue logic recv_ntb_t *recv_tinyusb_ntb; //!< buffer for the running transfer TinyUSB -> driver @@ -111,7 +92,7 @@ typedef struct { uint16_t recv_glue_ntb_datagram_ndx; //!< index into \a recv_glue_ntb_datagram // xmit handling - xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs + CFG_TUSB_MEM_ALIGN xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs xmit_ntb_t *xmit_free_ntb[XMIT_NTB_N]; //!< free list of xmit NTBs xmit_ntb_t *xmit_ready_ntb[XMIT_NTB_N]; //!< NTBs waiting for transmission to TinyUSB xmit_ntb_t *xmit_tinyusb_ntb; //!< buffer for the running transfer driver -> TinyUSB @@ -159,7 +140,7 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par // ==6 -> SystemView runs fine, iperf also // >6 -> iperf starts to show errors // -> 6 seems to be the best value. Why? Don't know, perhaps only on my system? -// switch \a INFO_OUT on to see interesting values for this. +// switch \a TU_LOG2 on to see interesting values for this. // // iperf: for MSS in 100 200 400 800 1200 1450 1500; do iperf -c 192.168.14.1 -e -i 1 -M $MSS -l 8192 -P 1; sleep 2; done // sysview: SYSTICKS_PER_SEC=35000, IDLE_US=1000, PRINT_MOD=1000 @@ -192,8 +173,8 @@ tu_static struct ncm_notify_t ncm_notify_speed_change = { .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE, .wLength = 8, }, - .downlink = 1000000, - .uplink = 1000000, + .downlink = 12000000, + .uplink = 12000000, }; @@ -204,28 +185,28 @@ static void notification_xmit(uint8_t rhport, bool force_next) * Notifications are transferred to the host once during connection setup. */ { - DEBUG_OUT("notification_xmit(%d, %d) - %d %d\n", force_next, rhport, ncm_interface.notification_xmit_state, ncm_interface.notification_xmit_is_running); + TU_LOG3("notification_xmit(%d, %d) - %d %d\n", force_next, rhport, ncm_interface.notification_xmit_state, ncm_interface.notification_xmit_is_running); if ( !force_next && ncm_interface.notification_xmit_is_running) { return; } if (ncm_interface.notification_xmit_state == NOTIFICATION_SPEED) { - DEBUG_OUT(" NOTIFICATION_SPEED\n"); + TU_LOG3(" NOTIFICATION_SPEED\n"); ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*) &ncm_notify_speed_change, sizeof(ncm_notify_speed_change)); ncm_interface.notification_xmit_state = NOTIFICATION_CONNECTED; ncm_interface.notification_xmit_is_running = true; } else if (ncm_interface.notification_xmit_state == NOTIFICATION_CONNECTED) { - DEBUG_OUT(" NOTIFICATION_CONNECTED\n"); + TU_LOG3(" NOTIFICATION_CONNECTED\n"); ncm_notify_connected.header.wIndex = ncm_interface.itf_num; usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*) &ncm_notify_connected, sizeof(ncm_notify_connected)); ncm_interface.notification_xmit_state = NOTIFICATION_DONE; ncm_interface.notification_xmit_is_running = true; } else { - DEBUG_OUT(" NOTIFICATION_FINISHED\n"); + TU_LOG3(" NOTIFICATION_FINISHED\n"); } } // notification_xmit @@ -241,7 +222,7 @@ static void xmit_put_ntb_into_free_list(xmit_ntb_t *free_ntb) * Put NTB into the transmitter free list. */ { - DEBUG_OUT("xmit_put_ntb_into_free_list() - %p\n", ncm_interface.xmit_tinyusb_ntb); + TU_LOG3("xmit_put_ntb_into_free_list() - %p\n", ncm_interface.xmit_tinyusb_ntb); if (free_ntb == NULL) { // can happen due to ZLPs @@ -254,7 +235,7 @@ static void xmit_put_ntb_into_free_list(xmit_ntb_t *free_ntb) return; } } - ERROR_OUT("(EE) xmit_put_ntb_into_free_list - no entry in free list\n"); // this should not happen + TU_LOG1("(EE) xmit_put_ntb_into_free_list - no entry in free list\n"); // this should not happen } // xmit_put_ntb_into_free_list @@ -264,7 +245,7 @@ static xmit_ntb_t *xmit_get_free_ntb(void) * Get an NTB from the free list */ { - DEBUG_OUT("xmit_get_free_ntb()\n"); + TU_LOG3("xmit_get_free_ntb()\n"); for (int i = 0; i < XMIT_NTB_N; ++i) { if (ncm_interface.xmit_free_ntb[i] != NULL) { @@ -283,7 +264,7 @@ static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) * Put a filled NTB into the ready list */ { - INFO_OUT("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); + TU_LOG2("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); for (int i = 0; i < XMIT_NTB_N; ++i) { if (ncm_interface.xmit_ready_ntb[i] == NULL) { @@ -291,7 +272,7 @@ static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) return; } } - ERROR_OUT("(EE) xmit_put_ntb_into_ready_list: ready list full\n"); // this should not happen + TU_LOG1("(EE) xmit_put_ntb_into_ready_list: ready list full\n"); // this should not happen } // xmit_put_ntb_into_ready_list @@ -308,13 +289,13 @@ static xmit_ntb_t *xmit_get_next_ready_ntb(void) memmove(ncm_interface.xmit_ready_ntb + 0, ncm_interface.xmit_ready_ntb + 1, sizeof(ncm_interface.xmit_ready_ntb) - sizeof(ncm_interface.xmit_ready_ntb[0])); ncm_interface.xmit_ready_ntb[XMIT_NTB_N - 1] = NULL; - DEBUG_OUT("recv_get_next_ready_ntb: %p\n", r); + TU_LOG3("recv_get_next_ready_ntb: %p\n", r); return r; } // xmit_get_next_ready_ntb -static bool xmit_insert_required_zlp(uint8_t rhport, uint16_t xferred_bytes) +static bool xmit_insert_required_zlp(uint8_t rhport, uint32_t xferred_bytes) /** * Transmit a ZLP if required * @@ -327,7 +308,7 @@ static bool xmit_insert_required_zlp(uint8_t rhport, uint16_t xferred_bytes) * This must be called from netd_xfer_cb() so that ep_in is ready */ { - DEBUG_OUT("xmit_insert_required_zlp(%d,%d)\n", rhport, xferred_bytes); + TU_LOG3("xmit_insert_required_zlp(%d,%d)\n", rhport, xferred_bytes); if (xferred_bytes == 0 || xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE != 0) { return false; @@ -336,7 +317,7 @@ static bool xmit_insert_required_zlp(uint8_t rhport, uint16_t xferred_bytes) TU_ASSERT(ncm_interface.itf_data_alt == 1, false); TU_ASSERT( !usbd_edpt_busy(rhport, ncm_interface.ep_in), false); - INFO_OUT("xmit_insert_required_zlp! (%u)\n", (unsigned)xferred_bytes); + TU_LOG2("xmit_insert_required_zlp! (%u)\n", (unsigned)xferred_bytes); // start transmission of the ZLP usbd_edpt_xfer(rhport, ncm_interface.ep_in, NULL, 0); @@ -351,18 +332,18 @@ static void xmit_start_if_possible(uint8_t rhport) * Start transmission if it there is a waiting packet and if can be done from interface side. */ { - DEBUG_OUT("xmit_start_if_possible()\n"); + TU_LOG3("xmit_start_if_possible()\n"); if (ncm_interface.xmit_tinyusb_ntb != NULL) { - DEBUG_OUT(" !xmit_start_if_possible 1\n"); + TU_LOG3(" !xmit_start_if_possible 1\n"); return; } if (ncm_interface.itf_data_alt != 1) { - ERROR_OUT("(II) !xmit_start_if_possible 2\n"); + TU_LOG1("(II) !xmit_start_if_possible 2\n"); return; } if (usbd_edpt_busy(rhport, ncm_interface.ep_in)) { - INFO_OUT(" !xmit_start_if_possible 3\n"); + TU_LOG2(" !xmit_start_if_possible 3\n"); return; } @@ -379,16 +360,16 @@ static void xmit_start_if_possible(uint8_t rhport) #ifdef DEBUG_OUT_ENABLED { uint16_t len = ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength; - DEBUG_OUT(" %d\n", len); + TU_LOG3(" %d\n", len); for (int i = 0; i < len; ++i) { - DEBUG_OUT(" %02x", ncm_interface.xmit_tinyusb_ntb->data[i]); + TU_LOG3(" %02x", ncm_interface.xmit_tinyusb_ntb->data[i]); } - DEBUG_OUT("\n"); + TU_LOG3("\n"); } #endif if (ncm_interface.xmit_glue_ntb_datagram_ndx != 1) { - DEBUG_OUT(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength, ncm_interface.xmit_glue_ntb_datagram_ndx); + TU_LOG3(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength, ncm_interface.xmit_glue_ntb_datagram_ndx); } // Kick off an endpoint transfer @@ -402,7 +383,7 @@ static bool xmit_requested_datagram_fits_into_current_ntb(uint16_t datagram_size * check if a new datagram fits into the current NTB */ { - DEBUG_OUT("xmit_requested_datagram_fits_into_current_ntb(%d) - %p %p\n", datagram_size, ncm_interface.xmit_tinyusb_ntb, ncm_interface.xmit_glue_ntb); + TU_LOG3("xmit_requested_datagram_fits_into_current_ntb(%d) - %p %p\n", datagram_size, ncm_interface.xmit_tinyusb_ntb, ncm_interface.xmit_glue_ntb); if (ncm_interface.xmit_glue_ntb == NULL) { return false; @@ -423,7 +404,7 @@ static bool xmit_setup_next_glue_ntb(void) * Setup an NTB for the glue logic */ { - DEBUG_OUT("xmit_setup_next_glue_ntb - %p\n", ncm_interface.xmit_glue_ntb); + TU_LOG3("xmit_setup_next_glue_ntb - %p\n", ncm_interface.xmit_glue_ntb); if (ncm_interface.xmit_glue_ntb != NULL) { // put NTB into waiting list (the new datagram did not fit in) @@ -432,7 +413,7 @@ static bool xmit_setup_next_glue_ntb(void) ncm_interface.xmit_glue_ntb = xmit_get_free_ntb(); // get next buffer (if any) if (ncm_interface.xmit_glue_ntb == NULL) { - DEBUG_OUT(" xmit_setup_next_glue_ntb - nothing free\n"); // should happen rarely + TU_LOG3(" xmit_setup_next_glue_ntb - nothing free\n"); // should happen rarely return false; } @@ -469,7 +450,7 @@ static recv_ntb_t *recv_get_free_ntb(void) * Returned buffer (if any) has the size \a CFG_TUD_NCM_OUT_NTB_MAX_SIZE. */ { - DEBUG_OUT("recv_get_free_ntb()\n"); + TU_LOG3("recv_get_free_ntb()\n"); for (int i = 0; i < RECV_NTB_N; ++i) { if (ncm_interface.recv_free_ntb[i] != NULL) { @@ -495,7 +476,7 @@ static recv_ntb_t *recv_get_next_ready_ntb(void) memmove(ncm_interface.recv_ready_ntb + 0, ncm_interface.recv_ready_ntb + 1, sizeof(ncm_interface.recv_ready_ntb) - sizeof(ncm_interface.recv_ready_ntb[0])); ncm_interface.recv_ready_ntb[RECV_NTB_N - 1] = NULL; - DEBUG_OUT("recv_get_next_ready_ntb: %p\n", r); + TU_LOG3("recv_get_next_ready_ntb: %p\n", r); return r; } // recv_get_next_ready_ntb @@ -506,7 +487,7 @@ static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) * */ { - DEBUG_OUT("recv_put_ntb_into_free_list(%p)\n", free_ntb); + TU_LOG3("recv_put_ntb_into_free_list(%p)\n", free_ntb); for (int i = 0; i < RECV_NTB_N; ++i) { if (ncm_interface.recv_free_ntb[i] == NULL) { @@ -514,7 +495,7 @@ static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) return; } } - ERROR_OUT("(EE) recv_put_ntb_into_free_list - no entry in free list\n"); // this should not happen + TU_LOG1("(EE) recv_put_ntb_into_free_list - no entry in free list\n"); // this should not happen } // recv_put_ntb_into_free_list @@ -525,7 +506,7 @@ static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) * put this buffer into the waiting list and free the receive logic. */ { - DEBUG_OUT("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); + TU_LOG3("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); for (int i = 0; i < RECV_NTB_N; ++i) { if (ncm_interface.recv_ready_ntb[i] == NULL) { @@ -533,7 +514,7 @@ static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) return; } } - ERROR_OUT("(EE) recv_put_ntb_into_ready_list: ready list full\n"); // this should not happen + TU_LOG1("(EE) recv_put_ntb_into_ready_list: ready list full\n"); // this should not happen } // recv_put_ntb_into_ready_list @@ -544,7 +525,7 @@ static void recv_try_to_start_new_reception(uint8_t rhport) * Return value is actually not of interest. */ { - DEBUG_OUT("recv_try_to_start_new_reception(%d)\n", rhport); + TU_LOG3("recv_try_to_start_new_reception(%d)\n", rhport); if (ncm_interface.itf_data_alt != 1) { return; @@ -552,7 +533,7 @@ static void recv_try_to_start_new_reception(uint8_t rhport) if (ncm_interface.recv_tinyusb_ntb != NULL) { return; } - if (usbd_edpt_busy(ncm_interface.rhport, ncm_interface.ep_out)) { + if (usbd_edpt_busy(rhport, ncm_interface.ep_out)) { return; } @@ -562,8 +543,8 @@ static void recv_try_to_start_new_reception(uint8_t rhport) } // initiate transfer - DEBUG_OUT(" start reception\n"); - bool r = usbd_edpt_xfer(0, ncm_interface.ep_out, ncm_interface.recv_tinyusb_ntb->data, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + TU_LOG3(" start reception\n"); + bool r = usbd_edpt_xfer(rhport, ncm_interface.ep_out, ncm_interface.recv_tinyusb_ntb->data, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); if ( !r) { recv_put_ntb_into_free_list(ncm_interface.recv_tinyusb_ntb); ncm_interface.recv_tinyusb_ntb = NULL; @@ -572,7 +553,7 @@ static void recv_try_to_start_new_reception(uint8_t rhport) -static bool recv_validate_datagram(const recv_ntb_t *ntb, uint16_t len) +static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) /** * Validate incoming datagram. * \return true if valid @@ -583,84 +564,86 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint16_t len) { const nth16_t *nth16 = &(ntb->nth); - DEBUG_OUT("recv_validate_datagram(%p)\n", ntb); + TU_LOG3("recv_validate_datagram(%p)\n", ntb); // // check header // if (nth16->wHeaderLength != sizeof(nth16_t)) { - ERROR_OUT("(EE) ill nth16 length: %d\n", nth16->wHeaderLength); + TU_LOG1("(EE) ill nth16 length: %d\n", nth16->wHeaderLength); return false; } if (nth16->dwSignature != NTH16_SIGNATURE) { - ERROR_OUT("(EE) ill signature: 0x%08x\n", (unsigned)nth16->dwSignature); + TU_LOG1("(EE) ill signature: 0x%08x\n", (unsigned)nth16->dwSignature); return false; } if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - ERROR_OUT("(EE) ill min len: %d\n", len); + TU_LOG1("(EE) ill min len: %d\n", len); return false; } if (nth16->wBlockLength > len) { - ERROR_OUT("(EE) ill block length: %d > %d\n", nth16->wBlockLength, len); + TU_LOG1("(EE) ill block length: %d > %d\n", nth16->wBlockLength, len); return false; } if (nth16->wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - ERROR_OUT("(EE) ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + TU_LOG1("(EE) ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); return false; } if (nth16->wNdpIndex < sizeof(nth16) || nth16->wNdpIndex > len - (sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t))) { - ERROR_OUT("(EE) ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); + TU_LOG1("(EE) ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); return false; } // // check (first) NDP(16) // - const ndp16_t *ndp16 = (ndp16_t *)(ntb->data + nth16->wNdpIndex); + const ndp16_t *ndp16 = (const ndp16_t *)(ntb->data + nth16->wNdpIndex); if (ndp16->wLength < sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - ERROR_OUT("(EE) ill ndp16 length: %d\n", ndp16->wLength); + TU_LOG1("(EE) ill ndp16 length: %d\n", ndp16->wLength); return false; } if (ndp16->dwSignature != NDP16_SIGNATURE_NCM0 && ndp16->dwSignature != NDP16_SIGNATURE_NCM1) { - ERROR_OUT("(EE) ill signature: 0x%08x\n", (unsigned)ndp16->dwSignature); + TU_LOG1("(EE) ill signature: 0x%08x\n", (unsigned)ndp16->dwSignature); return false; } if (ndp16->wNextNdpIndex != 0) { - ERROR_OUT("(EE) cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); + TU_LOG1("(EE) cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); return false; } - const ndp16_datagram_t *ndp16_datagram = (ndp16_datagram_t *)(ntb->data + nth16->wNdpIndex + sizeof(ndp16_t)); + const ndp16_datagram_t *ndp16_datagram = (const ndp16_datagram_t *)(ntb->data + nth16->wNdpIndex + sizeof(ndp16_t)); int ndx = 0; - int max_ndx = (ndp16->wLength - sizeof(ndp16_t)) / sizeof(ndp16_datagram_t); + uint16_t max_ndx = (uint16_t)((ndp16->wLength - sizeof(ndp16_t)) / sizeof(ndp16_datagram_t)); if (max_ndx > 2) { // number of datagrams in NTB > 1 - INFO_OUT("<< %d (%d)\n", max_ndx - 1, ntb->nth.wBlockLength); + TU_LOG2("<< %d (%d)\n", max_ndx - 1, ntb->nth.wBlockLength); } if (ndp16_datagram[max_ndx-1].wDatagramIndex != 0 || ndp16_datagram[max_ndx-1].wDatagramLength != 0) { - INFO_OUT(" max_ndx != 0\n"); + TU_LOG2(" max_ndx != 0\n"); return false; } while (ndp16_datagram[ndx].wDatagramIndex != 0 && ndp16_datagram[ndx].wDatagramLength != 0) { - DEBUG_OUT(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); + TU_LOG3(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); if (ndp16_datagram[ndx].wDatagramIndex > len) { - ERROR_OUT("(EE) ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); + TU_LOG1("(EE) ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); return false; } if (ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength > len) { - ERROR_OUT("(EE) ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); + TU_LOG1("(EE) ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); return false; } ++ndx; } - for (int i = 0; i < len; ++i) { - DEBUG_OUT(" %02x", ntb->data[i]); +#if CFG_TUSB_DEBUG >= 3 + for (uint32_t i = 0; i < len; ++i) { + TU_LOG3(" %02x", ntb->data[i]); } - DEBUG_OUT("\n"); + TU_LOG3("\n"); +#endif // -> ntb contains a valid packet structure // ok... I did not check for garbage within the datagram indices... @@ -674,11 +657,11 @@ static void recv_transfer_datagram_to_glue_logic(void) * Transfer the next (pending) datagram to the glue logic and return receive buffer if empty. */ { - DEBUG_OUT("recv_transfer_datagram_to_glue_logic()\n"); + TU_LOG3("recv_transfer_datagram_to_glue_logic()\n"); if (ncm_interface.recv_glue_ntb == NULL) { ncm_interface.recv_glue_ntb = recv_get_next_ready_ntb(); - DEBUG_OUT(" new buffer for glue logic: %p\n", ncm_interface.recv_glue_ntb); + TU_LOG3(" new buffer for glue logic: %p\n", ncm_interface.recv_glue_ntb); ncm_interface.recv_glue_ntb_datagram_ndx = 0; } @@ -688,21 +671,21 @@ static void recv_transfer_datagram_to_glue_logic(void) + sizeof(ndp16_t)); if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex == 0) { - ERROR_OUT("(EE) SOMETHING WENT WRONG 1\n"); + TU_LOG1("(EE) SOMETHING WENT WRONG 1\n"); } else if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength == 0) { - ERROR_OUT("(EE) SOMETHING WENT WRONG 2\n"); + TU_LOG1("(EE) SOMETHING WENT WRONG 2\n"); } else { uint16_t datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex; uint16_t datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength; - DEBUG_OUT(" recv[%d] - %d %d\n", ncm_interface.recv_glue_ntb_datagram_ndx, datagramIndex, datagramLength); + TU_LOG3(" recv[%d] - %d %d\n", ncm_interface.recv_glue_ntb_datagram_ndx, datagramIndex, datagramLength); if (tud_network_recv_cb(ncm_interface.recv_glue_ntb->data + datagramIndex, datagramLength)) { // // send datagram successfully to glue logic // - DEBUG_OUT(" OK\n"); + TU_LOG3(" OK\n"); datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramIndex; datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramLength; @@ -734,7 +717,7 @@ bool tud_network_can_xmit(uint16_t size) * and transmission operation. */ { - DEBUG_OUT("tud_network_can_xmit(%d)\n", size); + TU_LOG3("tud_network_can_xmit(%d)\n", size); TU_ASSERT(size <= CFG_TUD_NCM_OUT_NTB_MAX_SIZE - (sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)), false); @@ -743,7 +726,7 @@ bool tud_network_can_xmit(uint16_t size) return true; } xmit_start_if_possible(ncm_interface.rhport); - ERROR_OUT("(II) tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) + TU_LOG1("(II) tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) return false; } // tud_network_can_xmit @@ -755,10 +738,10 @@ void tud_network_xmit(void *ref, uint16_t arg) * If currently no transmission is started, then initiate transmission. */ { - DEBUG_OUT("tud_network_xmit(%p, %d)\n", ref, arg); + TU_LOG3("tud_network_xmit(%p, %d)\n", ref, arg); if (ncm_interface.xmit_glue_ntb == NULL) { - ERROR_OUT("(EE) tud_network_xmit: no buffer\n"); // must not happen (really) + TU_LOG1("(EE) tud_network_xmit: no buffer\n"); // must not happen (really) return; } @@ -772,10 +755,10 @@ void tud_network_xmit(void *ref, uint16_t arg) ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramLength = size; ncm_interface.xmit_glue_ntb_datagram_ndx += 1; - ntb->nth.wBlockLength += size + XMIT_ALIGN_OFFSET(size); + ntb->nth.wBlockLength += (uint16_t)(size + XMIT_ALIGN_OFFSET(size)); if (ntb->nth.wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - ERROR_OUT("(II) tud_network_xmit: buffer overflow\n"); // must not happen (really) + TU_LOG1("(II) tud_network_xmit: buffer overflow\n"); // must not happen (really) return; } @@ -789,7 +772,7 @@ void tud_network_recv_renew(void) * Keep the receive logic busy and transfer pending packets to the glue logic. */ { - DEBUG_OUT("tud_network_recv_renew()\n"); + TU_LOG3("tud_network_recv_renew()\n"); recv_transfer_datagram_to_glue_logic(); recv_try_to_start_new_reception(ncm_interface.rhport); @@ -802,7 +785,7 @@ void tud_network_recv_renew_r(uint8_t rhport) * Same as tud_network_recv_renew() but knows \a rhport */ { - DEBUG_OUT("tud_network_recv_renew_r(%d)\n", rhport); + TU_LOG3("tud_network_recv_renew_r(%d)\n", rhport); ncm_interface.rhport = rhport; tud_network_recv_renew(); @@ -819,7 +802,7 @@ void netd_init(void) * Might be called several times. */ { - DEBUG_OUT("netd_init()\n"); + TU_LOG3("netd_init()\n"); memset( &ncm_interface, 0, sizeof(ncm_interface)); @@ -839,7 +822,9 @@ void netd_reset(uint8_t rhport) * In this driver this is the same as netd_init() */ { - DEBUG_OUT("netd_reset(%d)\n", rhport); + (void)rhport; + + TU_LOG3("netd_reset(%d)\n", rhport); netd_init(); } // netd_reset @@ -862,7 +847,7 @@ uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16 * - USB interface is open */ { - DEBUG_OUT("netd_open(%d,%p,%d)\n", rhport, itf_desc, max_len); + TU_LOG3("netd_open(%d,%p,%d)\n", rhport, itf_desc, max_len); TU_ASSERT(ncm_interface.ep_notif == 0, 0); // assure that the interface is only opened once @@ -915,7 +900,9 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ * Handle TinyUSB requests to process transfer events. */ { - DEBUG_OUT("netd_xfer_cb(%d,%d,%d,%u)\n", rhport, ep_addr, result, (unsigned)xferred_bytes); + (void)result; + + TU_LOG3("netd_xfer_cb(%d,%d,%d,%u)\n", rhport, ep_addr, result, (unsigned)xferred_bytes); if (ep_addr == ncm_interface.ep_out) { // @@ -924,10 +911,10 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // - if ready transfer datagrams to the glue logic for further processing // - if there is a free receive buffer, initiate reception // - DEBUG_OUT(" EP_OUT %d %d %d %u\n", rhport, ep_addr, result, (unsigned)xferred_bytes); + TU_LOG3(" EP_OUT %d %d %d %u\n", rhport, ep_addr, result, (unsigned)xferred_bytes); if ( !recv_validate_datagram( ncm_interface.recv_tinyusb_ntb, xferred_bytes)) { // verification failed: ignore NTB and return it to free - ERROR_OUT("(EE) VALIDATION FAILED. WHAT CAN WE DO IN THIS CASE?\n"); + TU_LOG1("(EE) VALIDATION FAILED. WHAT CAN WE DO IN THIS CASE?\n"); } else { // packet ok -> put it into ready list @@ -943,7 +930,7 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // - insert ZLPs when necessary // - if there is another transmit NTB waiting, try to start transmission // - DEBUG_OUT(" EP_IN %d %u\n", ncm_interface.itf_data_alt, (unsigned)xferred_bytes); + TU_LOG3(" EP_IN %d %u\n", ncm_interface.itf_data_alt, (unsigned)xferred_bytes); xmit_put_ntb_into_free_list(ncm_interface.xmit_tinyusb_ntb); ncm_interface.xmit_tinyusb_ntb = NULL; if ( !xmit_insert_required_zlp(rhport, xferred_bytes)) { @@ -954,7 +941,7 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // // next transfer on notification channel // - DEBUG_OUT(" EP_NOTIF\n"); + TU_LOG3(" EP_NOTIF\n"); notification_xmit(rhport, true); } @@ -969,7 +956,7 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t * At startup transmission of notification packets are done here. */ { - DEBUG_OUT("netd_control_xfer_cb(%d, %d, %p)\n", rhport, stage, request); + TU_LOG3("netd_control_xfer_cb(%d, %d, %p)\n", rhport, stage, request); if (stage != CONTROL_STAGE_SETUP) { return true; @@ -981,7 +968,7 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t case TUSB_REQ_GET_INTERFACE: { TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex, false); - DEBUG_OUT(" TUSB_REQ_GET_INTERFACE - %d\n", ncm_interface.itf_data_alt); + TU_LOG3(" TUSB_REQ_GET_INTERFACE - %d\n", ncm_interface.itf_data_alt); tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); } break; @@ -989,8 +976,8 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t case TUSB_REQ_SET_INTERFACE: { TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex && request->wValue < 2, false); - ncm_interface.itf_data_alt = request->wValue; - DEBUG_OUT(" TUSB_REQ_SET_INTERFACE - %d %d %d\n", ncm_interface.itf_data_alt, request->wIndex, ncm_interface.itf_num); + ncm_interface.itf_data_alt = (uint8_t)request->wValue; + TU_LOG3(" TUSB_REQ_SET_INTERFACE - %d %d %d\n", ncm_interface.itf_data_alt, request->wIndex, ncm_interface.itf_num); if (ncm_interface.itf_data_alt == 1) { tud_network_recv_renew_r(rhport); @@ -1009,12 +996,12 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t case TUSB_REQ_TYPE_CLASS: TU_VERIFY(ncm_interface.itf_num == request->wIndex, false); - DEBUG_OUT(" TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); + TU_LOG3(" TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); if (request->bRequest == NCM_GET_NTB_PARAMETERS) { // transfer NTB parameters to host. // TODO can one assume, that tud_control_xfer() succeeds? - DEBUG_OUT(" NCM_GET_NTB_PARAMETERS\n"); + TU_LOG3(" NCM_GET_NTB_PARAMETERS\n"); tud_control_xfer(rhport, request, (void*) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); } break; -- cgit v1.3.1 From 92025b00f0a7d7d0b45d8a2bcc3f3704dbe77733 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 31 Aug 2023 20:32:42 +0200 Subject: code review: add NCM options in example config --- examples/device/net_lwip_webserver/src/tusb_config.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h index fe72ecdfe..025c0b0bf 100644 --- a/examples/device/net_lwip_webserver/src/tusb_config.h +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -82,6 +82,16 @@ #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif +// number of NCM transfer blocks for reception side (only valid if NCM is selected below) +#ifndef CFG_TUD_NCM_OUT_NTB_N +#define CFG_TUD_NCM_OUT_NTB_N 2 +#endif + +// number of NCM transfer blocks for transmission side (only valid if NCM is selected below) +#ifndef CFG_TUD_NCM_IN_NTB_N +#define CFG_TUD_NCM_IN_NTB_N 3 +#endif + //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- @@ -94,8 +104,8 @@ // Network class has 2 drivers: ECM/RNDIS and NCM. // Only one of the drivers can be enabled -#define CFG_TUD_ECM_RNDIS 1 -#define CFG_TUD_NCM (1-CFG_TUD_ECM_RNDIS) +#define CFG_TUD_ECM_RNDIS 0 +#define CFG_TUD_NCM (1-CFG_TUD_ECM_RNDIS) #ifdef __cplusplus } -- cgit v1.3.1 From 51ea467350f84b92439d0890a4b12bd55e2eff91 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 31 Aug 2023 20:34:12 +0200 Subject: removed debug comment --- src/class/net/ncm_device.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index d0832cf73..9adb3df0d 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -134,18 +134,6 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par .wNtbOutMaxDatagrams = 6 // 0=no limit }; -// Some confusing remarks about wNtbOutMaxDatagrams... -// ==1 -> SystemView packets/s goes up to 2000 and events are lost during startup -// ==0 -> SystemView runs fine, iperf shows in wireshark a lot of error -// ==6 -> SystemView runs fine, iperf also -// >6 -> iperf starts to show errors -// -> 6 seems to be the best value. Why? Don't know, perhaps only on my system? -// switch \a TU_LOG2 on to see interesting values for this. -// -// iperf: for MSS in 100 200 400 800 1200 1450 1500; do iperf -c 192.168.14.1 -e -i 1 -M $MSS -l 8192 -P 1; sleep 2; done -// sysview: SYSTICKS_PER_SEC=35000, IDLE_US=1000, PRINT_MOD=1000 -// - //----------------------------------------------------------------------------- // // everything about notifications -- cgit v1.3.1 From 745c154dbc33bff9a45bc8bee636e7e90152a9c7 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 8 Sep 2023 07:00:08 +0200 Subject: ECM/RNDIS again selected for webserver example --- examples/device/net_lwip_webserver/src/tusb_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h index 025c0b0bf..841525cad 100644 --- a/examples/device/net_lwip_webserver/src/tusb_config.h +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -104,7 +104,7 @@ // Network class has 2 drivers: ECM/RNDIS and NCM. // Only one of the drivers can be enabled -#define CFG_TUD_ECM_RNDIS 0 +#define CFG_TUD_ECM_RNDIS 1 #define CFG_TUD_NCM (1-CFG_TUD_ECM_RNDIS) #ifdef __cplusplus -- cgit v1.3.1 From f1d3663d24f04dbb68732f8287c516abd0b7ecfb Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 8 Sep 2023 07:01:13 +0200 Subject: minor changes to comments and debug output --- src/class/net/ncm_device.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 9adb3df0d..d803d6429 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -59,11 +59,6 @@ #include "ncm.h" -#if !defined(tu_static) || defined(ECLIPSE_GUI) - // TinyUSB <=0.15.0 does not know "tu_static" - #define tu_static static -#endif - // calculate alignment of xmit datagrams within an NTB #define XMIT_ALIGN_OFFSET(x) ((CFG_TUD_NCM_ALIGNMENT - ((x) & (CFG_TUD_NCM_ALIGNMENT - 1))) & (CFG_TUD_NCM_ALIGNMENT - 1)) @@ -84,7 +79,7 @@ typedef struct { uint8_t rhport; //!< storage of \a rhport because some callbacks are done without it // recv handling - CFG_TUSB_MEM_ALIGN recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs + CFG_TUSB_MEM_ALIGN recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs recv_ntb_t *recv_free_ntb[RECV_NTB_N]; //!< free list of recv NTBs recv_ntb_t *recv_ready_ntb[RECV_NTB_N]; //!< NTBs waiting for transmission to glue logic recv_ntb_t *recv_tinyusb_ntb; //!< buffer for the running transfer TinyUSB -> driver @@ -92,7 +87,7 @@ typedef struct { uint16_t recv_glue_ntb_datagram_ndx; //!< index into \a recv_glue_ntb_datagram // xmit handling - CFG_TUSB_MEM_ALIGN xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs + CFG_TUSB_MEM_ALIGN xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs xmit_ntb_t *xmit_free_ntb[XMIT_NTB_N]; //!< free list of xmit NTBs xmit_ntb_t *xmit_ready_ntb[XMIT_NTB_N]; //!< NTBs waiting for transmission to TinyUSB xmit_ntb_t *xmit_tinyusb_ntb; //!< buffer for the running transfer driver -> TinyUSB @@ -327,7 +322,7 @@ static void xmit_start_if_possible(uint8_t rhport) return; } if (ncm_interface.itf_data_alt != 1) { - TU_LOG1("(II) !xmit_start_if_possible 2\n"); + TU_LOG1("(EE) !xmit_start_if_possible 2\n"); return; } if (usbd_edpt_busy(rhport, ncm_interface.ep_in)) { @@ -472,7 +467,7 @@ static recv_ntb_t *recv_get_next_ready_ntb(void) static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) /** - * + * Put NTB into the receiver free list. */ { TU_LOG3("recv_put_ntb_into_free_list(%p)\n", free_ntb); @@ -490,8 +485,8 @@ static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) /** - * The \a ncm_interface.recv_tinyusb_ntb is filled, - * put this buffer into the waiting list and free the receive logic. + * \a ready_ntb holds a validated NTB, + * put this buffer into the waiting list. */ { TU_LOG3("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); @@ -510,7 +505,6 @@ static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) static void recv_try_to_start_new_reception(uint8_t rhport) /** * If possible, start a new reception TinyUSB -> driver. - * Return value is actually not of interest. */ { TU_LOG3("recv_try_to_start_new_reception(%d)\n", rhport); @@ -552,7 +546,7 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) { const nth16_t *nth16 = &(ntb->nth); - TU_LOG3("recv_validate_datagram(%p)\n", ntb); + TU_LOG3("recv_validate_datagram(%p, %d)\n", ntb, (int)len); // // check header @@ -714,7 +708,7 @@ bool tud_network_can_xmit(uint16_t size) return true; } xmit_start_if_possible(ncm_interface.rhport); - TU_LOG1("(II) tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) + TU_LOG2("tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) return false; } // tud_network_can_xmit @@ -746,7 +740,7 @@ void tud_network_xmit(void *ref, uint16_t arg) ntb->nth.wBlockLength += (uint16_t)(size + XMIT_ALIGN_OFFSET(size)); if (ntb->nth.wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - TU_LOG1("(II) tud_network_xmit: buffer overflow\n"); // must not happen (really) + TU_LOG1("(EE) tud_network_xmit: buffer overflow\n"); // must not happen (really) return; } -- cgit v1.3.1 From 3e8cf3ec8c861233c2a15750a38c38deb2302094 Mon Sep 17 00:00:00 2001 From: Ryan Solorzano Date: Tue, 12 Sep 2023 11:32:23 -0700 Subject: Add HID Lighting and Illumination functionality --- src/class/hid/hid.h | 96 +++++++++++++++++--------- src/class/hid/hid_device.h | 165 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 231 insertions(+), 30 deletions(-) diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index fbd3eef38..ecc9c04a7 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -684,32 +684,33 @@ enum { /// HID Usage Table - Table 1: Usage Page Summary enum { - HID_USAGE_PAGE_DESKTOP = 0x01, - HID_USAGE_PAGE_SIMULATE = 0x02, - HID_USAGE_PAGE_VIRTUAL_REALITY = 0x03, - HID_USAGE_PAGE_SPORT = 0x04, - HID_USAGE_PAGE_GAME = 0x05, - HID_USAGE_PAGE_GENERIC_DEVICE = 0x06, - HID_USAGE_PAGE_KEYBOARD = 0x07, - HID_USAGE_PAGE_LED = 0x08, - HID_USAGE_PAGE_BUTTON = 0x09, - HID_USAGE_PAGE_ORDINAL = 0x0a, - HID_USAGE_PAGE_TELEPHONY = 0x0b, - HID_USAGE_PAGE_CONSUMER = 0x0c, - HID_USAGE_PAGE_DIGITIZER = 0x0d, - HID_USAGE_PAGE_PID = 0x0f, - HID_USAGE_PAGE_UNICODE = 0x10, - HID_USAGE_PAGE_ALPHA_DISPLAY = 0x14, - HID_USAGE_PAGE_MEDICAL = 0x40, - HID_USAGE_PAGE_MONITOR = 0x80, //0x80 - 0x83 - HID_USAGE_PAGE_POWER = 0x84, // 0x084 - 0x87 - HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c, - HID_USAGE_PAGE_SCALE = 0x8d, - HID_USAGE_PAGE_MSR = 0x8e, - HID_USAGE_PAGE_CAMERA = 0x90, - HID_USAGE_PAGE_ARCADE = 0x91, - HID_USAGE_PAGE_FIDO = 0xF1D0, // FIDO alliance HID usage page - HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF + HID_USAGE_PAGE_DESKTOP = 0x01, + HID_USAGE_PAGE_SIMULATE = 0x02, + HID_USAGE_PAGE_VIRTUAL_REALITY = 0x03, + HID_USAGE_PAGE_SPORT = 0x04, + HID_USAGE_PAGE_GAME = 0x05, + HID_USAGE_PAGE_GENERIC_DEVICE = 0x06, + HID_USAGE_PAGE_KEYBOARD = 0x07, + HID_USAGE_PAGE_LED = 0x08, + HID_USAGE_PAGE_BUTTON = 0x09, + HID_USAGE_PAGE_ORDINAL = 0x0a, + HID_USAGE_PAGE_TELEPHONY = 0x0b, + HID_USAGE_PAGE_CONSUMER = 0x0c, + HID_USAGE_PAGE_DIGITIZER = 0x0d, + HID_USAGE_PAGE_PID = 0x0f, + HID_USAGE_PAGE_UNICODE = 0x10, + HID_USAGE_PAGE_ALPHA_DISPLAY = 0x14, + HID_USAGE_PAGE_MEDICAL = 0x40, + HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION = 0x59, + HID_USAGE_PAGE_MONITOR = 0x80, //0x80 - 0x83 + HID_USAGE_PAGE_POWER = 0x84, // 0x084 - 0x87 + HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c, + HID_USAGE_PAGE_SCALE = 0x8d, + HID_USAGE_PAGE_MSR = 0x8e, + HID_USAGE_PAGE_CAMERA = 0x90, + HID_USAGE_PAGE_ARCADE = 0x91, + HID_USAGE_PAGE_FIDO = 0xF1D0, // FIDO alliance HID usage page + HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF }; /// HID Usage Table - Table 6: Generic Desktop Page @@ -788,8 +789,7 @@ enum { /// HID Usage Table: Consumer Page (0x0C) /// Only contains controls that supported by Windows (whole list is too long) -enum -{ +enum { // Generic Control HID_USAGE_CONSUMER_CONTROL = 0x0001, @@ -845,9 +845,45 @@ enum HID_USAGE_CONSUMER_AC_PAN = 0x0238, }; +/// HID Usage Table - Lighting And Illumination Page (0x59) +enum { + HID_USAGE_LIGHTING_LAMP_ARRAY = 0x01, + HID_USAGE_LIGHTING_LAMP_ARRAY_ATTRIBUTES_REPORT = 0x02, + HID_USAGE_LIGHTING_LAMP_COUNT = 0x03, + HID_USAGE_LIGHTING_BOUNDING_BOX_WIDTH_IN_MICROMETERS = 0x04, + HID_USAGE_LIGHTING_BOUNDING_BOX_HEIGHT_IN_MICROMETERS = 0x05, + HID_USAGE_LIGHTING_BOUNDING_BOX_DEPTH_IN_MICROMETERS = 0x06, + HID_USAGE_LIGHTING_LAMP_ARRAY_KIND = 0x07, + HID_USAGE_LIGHTING_MIN_UPDATE_INTERVAL_IN_MICROSECONDS = 0x08, + HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_REQUEST_REPORT = 0x20, + HID_USAGE_LIGHTING_LAMP_ID = 0x21, + HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_RESPONSE_REPORT = 0x22, + HID_USAGE_LIGHTING_POSITION_X_IN_MICROMETERS = 0x23, + HID_USAGE_LIGHTING_POSITION_Y_IN_MICROMETERS = 0x24, + HID_USAGE_LIGHTING_POSITION_Z_IN_MICROMETERS = 0x25, + HID_USAGE_LIGHTING_LAMP_PURPOSES = 0x26, + HID_USAGE_LIGHTING_UPDATE_LATENCY_IN_MICROSECONDS = 0x27, + HID_USAGE_LIGHTING_RED_LEVEL_COUNT = 0x28, + HID_USAGE_LIGHTING_GREEN_LEVEL_COUNT = 0x29, + HID_USAGE_LIGHTING_BLUE_LEVEL_COUNT = 0x2A, + HID_USAGE_LIGHTING_INTENSITY_LEVEL_COUNT = 0x2B, + HID_USAGE_LIGHTING_IS_PROGRAMMABLE = 0x2C, + HID_USAGE_LIGHTING_INPUT_BINDING = 0x2D, + HID_USAGE_LIGHTING_LAMP_MULTI_UPDATE_REPORT = 0x50, + HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL = 0x51, + HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL = 0x52, + HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL = 0x53, + HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL = 0x54, + HID_USAGE_LIGHTING_LAMP_UPDATE_FLAGS = 0x55, + HID_USAGE_LIGHTING_LAMP_RANGE_UPDATE_REPORT = 0x60, + HID_USAGE_LIGHTING_LAMP_ID_START = 0x61, + HID_USAGE_LIGHTING_LAMP_ID_END = 0x62, + HID_USAGE_LIGHTING_LAMP_ARRAY_CONTROL_REPORT = 0x70, + HID_USAGE_LIGHTING_AUTONOMOUS_MODE = 0x71, +}; + /// HID Usage Table: FIDO Alliance Page (0xF1D0) -enum -{ +enum { HID_USAGE_FIDO_U2FHID = 0x01, // U2FHID usage for top-level collection HID_USAGE_FIDO_DATA_IN = 0x20, // Raw IN data report HID_USAGE_FIDO_DATA_OUT = 0x21 // Raw OUT data report diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 17b24def1..276db894d 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -402,6 +402,171 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_COLLECTION_END \ +// HID Lighting and Illumination Report Descriptor Template +// - 1st parameter is report id HID_REPORT_ID(n) (optional) +#define TUD_HID_REPORT_DESC_LIGHTING(report_id) \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY ),\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\ + /* Lamp Array Attributes Report */ \ + HID_REPORT_ID (report_id ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY_ATTRIBUTES_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_COUNT ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 65535, 3 ),\ + HID_REPORT_SIZE ( 16 ),\ + HID_REPORT_COUNT ( 1 ),\ + HID_FEATURE ( HID_CONSTANT | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BOUNDING_BOX_WIDTH_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BOUNDING_BOX_HEIGHT_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BOUNDING_BOX_DEPTH_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY_KIND ),\ + HID_USAGE ( HID_USAGE_LIGHTING_MIN_UPDATE_INTERVAL_IN_MICROSECONDS ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 2147483647, 3 ),\ + HID_REPORT_SIZE ( 32 ),\ + HID_REPORT_COUNT ( 5 ),\ + HID_FEATURE ( HID_CONSTANT | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + /* Lamp Attributes Request Report */ \ + HID_REPORT_ID ( report_id + 1 ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_REQUEST_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 65535, 3 ),\ + HID_REPORT_SIZE ( 16 ),\ + HID_REPORT_COUNT ( 1 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + /* Lamp Attributes Response Report */ \ + HID_REPORT_ID ( report_id + 2 ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_RESPONSE_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 65535, 3 ),\ + HID_REPORT_SIZE ( 16 ),\ + HID_REPORT_COUNT ( 1 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_POSITION_X_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_POSITION_Y_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_POSITION_Z_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_UPDATE_LATENCY_IN_MICROSECONDS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_PURPOSES ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 2147483647, 3 ),\ + HID_REPORT_SIZE ( 32 ),\ + HID_REPORT_COUNT ( 5 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_LEVEL_COUNT ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_LEVEL_COUNT ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_LEVEL_COUNT ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_LEVEL_COUNT ),\ + HID_USAGE ( HID_USAGE_LIGHTING_IS_PROGRAMMABLE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INPUT_BINDING ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 255, 2 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 6 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + /* Lamp Multi-Update Report */ \ + HID_REPORT_ID ( report_id + 3 ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_MULTI_UPDATE_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_COUNT ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_UPDATE_FLAGS ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX ( 8 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 2 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 65535, 3 ),\ + HID_REPORT_SIZE ( 16 ),\ + HID_REPORT_COUNT ( 8 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 255, 2 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 32 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + /* Lamp Range Update Report */ \ + HID_REPORT_ID ( report_id + 4 ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_RANGE_UPDATE_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_UPDATE_FLAGS ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX ( 8 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 1 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID_START ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID_END ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 65535, 3 ),\ + HID_REPORT_SIZE ( 16 ),\ + HID_REPORT_COUNT ( 2 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 255, 2 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 4 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + /* Lamp Array Control Report */ \ + HID_REPORT_ID ( report_id + 5 ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY_CONTROL_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_AUTONOMOUS_MODE ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX ( 1 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 1 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + HID_COLLECTION_END \ + //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -- cgit v1.3.1 From a3d9eb43f1f0bd1632e4d8fe4fb3f3fc57778f16 Mon Sep 17 00:00:00 2001 From: Ryan Solorzano Date: Tue, 12 Sep 2023 12:09:39 -0700 Subject: Update Lighting Descriptor Template comment --- src/class/hid/hid_device.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 276db894d..966cfd9d1 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -403,7 +403,14 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y HID_COLLECTION_END \ // HID Lighting and Illumination Report Descriptor Template -// - 1st parameter is report id HID_REPORT_ID(n) (optional) +// - 1st parameter is report id (required) +// Creates 6 report ids for lighting HID usages in the following order: +// report_id+0: HID_USAGE_LIGHTING_LAMP_ARRAY_ATTRIBUTES_REPORT +// report_id+1: HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_REQUEST_REPORT +// report_id+2: HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_RESPONSE_REPORT +// report_id+3: HID_USAGE_LIGHTING_LAMP_MULTI_UPDATE_REPORT +// report_id+4: HID_USAGE_LIGHTING_LAMP_RANGE_UPDATE_REPORT +// report_id+5: HID_USAGE_LIGHTING_LAMP_ARRAY_CONTROL_REPORT #define TUD_HID_REPORT_DESC_LIGHTING(report_id) \ HID_USAGE_PAGE ( HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION ),\ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY ),\ -- cgit v1.3.1 From 11fba8433474a0653047823a25a749183a7d1ac2 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Wed, 13 Sep 2023 21:29:04 +0000 Subject: Error handling on transfer --- src/class/hid/hid_device.c | 25 +++++++++++++++++++++---- src/class/hid/hid_device.h | 4 ++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 5637ea6b4..8bedb6395 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -381,8 +381,6 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - (void) result; - uint8_t instance = 0; hidd_interface_t * p_hid = _hidd_itf; @@ -394,6 +392,25 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ } TU_ASSERT(instance < CFG_TUD_HID); + // Check if there was a problem + if (XFER_RESULT_SUCCESS != result) + { + // Inform application about the issue + if (tud_hid_report_issue_cb) + { + tud_hid_report_issue_cb(instance, ep_addr, result, xferred_bytes); + } + + // Allow a new transfer to be received if issue happened on an OUT endpoint + if (ep_addr == p_hid->ep_out) + { + // Prepare the OUT endpoint to be able to receive a new transfer + TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); + } + + return true; + } + // Sent report successfully if (ep_addr == p_hid->ep_in) { @@ -402,10 +419,10 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t) xferred_bytes); } } - // Received report + // Received report successfully else if (ep_addr == p_hid->ep_out) { - tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_INVALID, p_hid->epout_buf, (uint16_t) xferred_bytes); + tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t) xferred_bytes); TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); } diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 17b24def1..056727378 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -118,6 +118,8 @@ TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); // Note: For composite reports, report[0] is report ID TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); +// Invoked when a transfer wasn't successful +TU_ATTR_WEAK void tud_hid_report_issue_cb(uint8_t instance, uint8_t ep_addr, xfer_result_t result, uint16_t xferred_bytes); //--------------------------------------------------------------------+ // Inline Functions @@ -411,6 +413,8 @@ uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool hidd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); +void test(void); + #ifdef __cplusplus } #endif -- cgit v1.3.1 From 81e63ed6d865d43b634ed6bf2d3df3ae29135913 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Wed, 13 Sep 2023 22:03:44 +0000 Subject: Fixing warning --- src/class/hid/hid_device.c | 2 +- src/class/hid/hid_device.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 8bedb6395..564ad12f6 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -398,7 +398,7 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // Inform application about the issue if (tud_hid_report_issue_cb) { - tud_hid_report_issue_cb(instance, ep_addr, result, xferred_bytes); + tud_hid_report_issue_cb(instance, ep_addr, result, (uint16_t) xferred_bytes); } // Allow a new transfer to be received if issue happened on an OUT endpoint diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 056727378..a934753eb 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -119,7 +119,7 @@ TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); // Invoked when a transfer wasn't successful -TU_ATTR_WEAK void tud_hid_report_issue_cb(uint8_t instance, uint8_t ep_addr, xfer_result_t result, uint16_t xferred_bytes); +TU_ATTR_WEAK void tud_hid_report_issue_cb(uint8_t instance, uint8_t ep_addr, xfer_result_t result, uint16_t len); //--------------------------------------------------------------------+ // Inline Functions -- cgit v1.3.1 From 997c29ba0517604859a13aa73a8a80341d549898 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Thu, 14 Sep 2023 18:46:56 +0000 Subject: SOF ISR control --- src/device/usbd.c | 45 ++++++++++++++++++++++++++++++++++++++++----- src/device/usbd.h | 4 ++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 226896b37..60cd3167d 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -267,6 +267,21 @@ static inline usbd_class_driver_t const * get_driver(uint8_t drvid) #define TOTAL_DRIVER_COUNT (_app_driver_count + BUILTIN_DRIVER_COUNT) +typedef struct +{ + union + { + struct + { + uint8_t count : 7; + uint8_t cb_en : 1; + } + uint8_t value; + } +} usbd_sof_t; + +tu_static usbd_sof_t _usbd_sof = { .value = 0 }; + //--------------------------------------------------------------------+ // DCD Event //--------------------------------------------------------------------+ @@ -380,6 +395,14 @@ bool tud_connect(void) return true; } +bool tud_sof_cb_enable(bool en) +{ + TU_VERIFY(dcd_sof_enable); + _usbd_sof.cb_en = en; + dcd_sof_enable(rhport, _usbd_sof.value ? true : false); + return true; +} + //--------------------------------------------------------------------+ // USBD Task //--------------------------------------------------------------------+ @@ -597,8 +620,11 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) break; case DCD_EVENT_SOF: - TU_LOG_USBD("\r\n"); - if ( tud_sof_cb ) tud_sof_cb(event->sof.frame_count); + if ( _usbd_sof.cb_en) + { + TU_LOG_USBD("\r\n"); + if ( tud_sof_cb ) tud_sof_cb(event->sof.frame_count); + } break; default: @@ -1389,9 +1415,18 @@ void usbd_sof_enable(uint8_t rhport, bool en) { rhport = _usbd_rhport; - // TODO: Check needed if all drivers including the user sof_cb does not need an active SOF ISR any more. - // Only if all drivers switched off SOF calls the SOF interrupt may be disabled - dcd_sof_enable(rhport, en); + // Keep track how many class instances need the SOF interrupt + if (en) + { + _usbd_sof.count++; + } + else + { + _usbd_sof.count--; + } + + // Only disable SOF interrupts if all drivers switched off SOF calls and if the SOF callback isn't used + dcd_sof_enable(rhport, _usbd_sof.value ? true : false); } bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) diff --git a/src/device/usbd.h b/src/device/usbd.h index 423cd7053..3831cdfcf 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -96,6 +96,10 @@ bool tud_disconnect(void); // Return false on unsupported MCUs bool tud_connect(void); +// Enable or disable the Start Of Frame callback support +// Return false on unsupported MCUs +bool tud_sof_cb_enable(bool en); + // Carry out Data and Status stage of control transfer // - If len = 0, it is equivalent to sending status only // - If len > wLength : it will be truncated -- cgit v1.3.1 From 288f24b294a96f8edc12943d21278020e3e398e3 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Thu, 14 Sep 2023 18:50:13 +0000 Subject: Missing semicolon --- src/device/usbd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 60cd3167d..83d09a359 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -275,9 +275,9 @@ typedef struct { uint8_t count : 7; uint8_t cb_en : 1; - } + }; uint8_t value; - } + }; } usbd_sof_t; tu_static usbd_sof_t _usbd_sof = { .value = 0 }; -- cgit v1.3.1 From 46977a011d88b8954083de0fc8201350bcda5884 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Thu, 14 Sep 2023 18:53:55 +0000 Subject: Fixign errors --- src/device/usbd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 83d09a359..1ca5cc9cf 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -399,7 +399,7 @@ bool tud_sof_cb_enable(bool en) { TU_VERIFY(dcd_sof_enable); _usbd_sof.cb_en = en; - dcd_sof_enable(rhport, _usbd_sof.value ? true : false); + dcd_sof_enable(_usbd_rhport, _usbd_sof.value ? true : false); return true; } @@ -623,7 +623,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) if ( _usbd_sof.cb_en) { TU_LOG_USBD("\r\n"); - if ( tud_sof_cb ) tud_sof_cb(event->sof.frame_count); + if ( tud_sof_cb ) tud_sof_cb(event.sof.frame_count); } break; -- cgit v1.3.1 From c87fba1dc3b8cc8a1f72aca312bb5c0d1312464b Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Thu, 14 Sep 2023 19:03:16 +0000 Subject: Bug --- src/device/usbd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 1ca5cc9cf..ff57f5cad 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -397,7 +397,6 @@ bool tud_connect(void) bool tud_sof_cb_enable(bool en) { - TU_VERIFY(dcd_sof_enable); _usbd_sof.cb_en = en; dcd_sof_enable(_usbd_rhport, _usbd_sof.value ? true : false); return true; -- cgit v1.3.1 From 337d03d36883c5067d102900e6ce14e98ce3f8f0 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Thu, 14 Sep 2023 19:16:45 +0000 Subject: Incorrect comment --- src/device/usbd.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/device/usbd.h b/src/device/usbd.h index 3831cdfcf..1de51af3e 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -97,7 +97,6 @@ bool tud_disconnect(void); bool tud_connect(void); // Enable or disable the Start Of Frame callback support -// Return false on unsupported MCUs bool tud_sof_cb_enable(bool en); // Carry out Data and Status stage of control transfer -- cgit v1.3.1 From f88a5bb03b2504df272d2cd285b17e66f11dfc64 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Tue, 17 Oct 2023 19:26:11 -0700 Subject: hid_device: use separate buffer for SET_REPORT instead of epout --- src/class/hid/hid_device.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 2d46d760f..c939c0117 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -52,6 +52,7 @@ typedef struct CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t set_report_buf[CFG_TUD_HID_EP_BUFSIZE]; // TODO save hid descriptor since host can specifically request this after enumeration // Note: HID descriptor may be not available from application after enumeration @@ -307,15 +308,15 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t case HID_REQ_CONTROL_SET_REPORT: if ( stage == CONTROL_STAGE_SETUP ) { - TU_VERIFY(request->wLength <= sizeof(p_hid->epout_buf)); - tud_control_xfer(rhport, request, p_hid->epout_buf, request->wLength); + TU_VERIFY(request->wLength <= sizeof(p_hid->set_report_buf)); + tud_control_xfer(rhport, request, p_hid->set_report_buf, request->wLength); } else if ( stage == CONTROL_STAGE_ACK ) { uint8_t const report_type = tu_u16_high(request->wValue); uint8_t const report_id = tu_u16_low(request->wValue); - uint8_t const* report_buf = p_hid->epout_buf; + uint8_t const* report_buf = p_hid->set_report_buf; uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); // If host request a specific Report ID, extract report ID in buffer before invoking callback -- cgit v1.3.1 From 1755bba509edf2d5bc49cadecb6e956497732b37 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Mon, 15 Jan 2024 12:47:13 +0000 Subject: Add DWC2 Test Mode SUpport --- src/common/tusb_mcu.h | 2 ++ src/device/dcd.h | 28 ++++++++++++++++++ src/device/usbd.c | 53 +++++++++++++++++++++++++++++++---- src/portable/synopsys/dwc2/dcd_dwc2.c | 30 ++++++++++++++++++++ 4 files changed, 107 insertions(+), 6 deletions(-) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 35f94efbc..146accabf 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -195,6 +195,7 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32F7) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 + #define TUP_USBIP_DWC2_TEST_MODE_SUPPORT // FS has 6, HS has 9 #define TUP_DCD_ENDPOINT_MAX 9 @@ -262,6 +263,7 @@ #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_USBIP_DWC2_TEST_MODE_SUPPORT #elif TU_CHECK_MCU(OPT_MCU_STM32L5) #define TUP_USBIP_FSDEV diff --git a/src/device/dcd.h b/src/device/dcd.h index 18a708347..7755ef107 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -58,6 +58,7 @@ typedef enum DCD_EVENT_SETUP_RECEIVED, DCD_EVENT_XFER_COMPLETE, + DCD_EVENT_TEST_MODE, // Not an DCD event, just a convenient way to defer ISR function USBD_EVENT_FUNC_CALL, @@ -97,9 +98,23 @@ typedef struct TU_ATTR_ALIGNED(4) void (*func) (void*); void* param; }func_call; + + // TEST MODE + struct { + uint8_t selector; + }test_mode; }; } dcd_event_t; +typedef enum _test_mode_selector +{ + TEST_J = 1, + TEST_K, + TEST_SE0_NAK, + TEST_PACKET, + TEST_FORCE_ENABLE, +} test_mode_t; + //TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct"); //--------------------------------------------------------------------+ @@ -149,6 +164,12 @@ void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK; // Enable/Disable Start-of-frame interrupt. Default is disabled void dcd_sof_enable(uint8_t rhport, bool en); +// Check if the test mode is supported +bool dcd_test_mode_supported(test_mode_t test_selector) TU_ATTR_WEAK; + +// Put device into a test mode (needs power cycle to quit) +void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) TU_ATTR_WEAK; + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ @@ -240,6 +261,13 @@ static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_i dcd_event_handler(&event, in_isr); } +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_enter_test_mode(uint8_t rhport, uint8_t test_selector, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_TEST_MODE }; + event.test_mode.selector = test_selector; + dcd_event_handler(&event, in_isr); +} + #ifdef __cplusplus } #endif diff --git a/src/device/usbd.c b/src/device/usbd.c index f0d9fba52..90fde92b5 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -587,6 +587,11 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) if ( event.func_call.func ) event.func_call.func(event.func_call.param); break; + case DCD_EVENT_TEST_MODE: + TU_LOG_USBD(": Enter Test Mode with selector index = %d)\r\n", event.test_mode.selector); + if (dcd_enter_test_mode) dcd_enter_test_mode(event.rhport, event.test_mode.selector); + break; + case DCD_EVENT_SOF: default: TU_BREAKPOINT(); @@ -725,14 +730,50 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const break; case TUSB_REQ_SET_FEATURE: - // Only support remote wakeup for device feature - TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue); + // Handle the feature selector + switch(p_request->wValue) + { + // Support for remote wakeup + case TUSB_REQ_FEATURE_REMOTE_WAKEUP: + TU_LOG_USBD(" Enable Remote Wakeup\r\n"); - TU_LOG_USBD(" Enable Remote Wakeup\r\n"); + // Host may enable remote wake up before suspending especially HID device + _usbd_dev.remote_wakeup_en = true; + tud_control_status(rhport, p_request); - // Host may enable remote wake up before suspending especially HID device - _usbd_dev.remote_wakeup_en = true; - tud_control_status(rhport, p_request); + break; + + // Support for TEST_MODE + case TUSB_REQ_FEATURE_TEST_MODE: + // Only handle the test mode is supported and valid + if (!dcd_enter_test_mode || !dcd_test_mode_supported || 0 != tu_u16_low(p_request->wIndex)) + { + return false; + } + + uint8_t selector = tu_u16_high(p_request->wIndex); + + // Stall request if the selected test mode isn't supported + if (!dcd_test_mode_supported(selector)) + { + TU_LOG_USBD(" Unsupported Test Mode (test selector index: %d)\r\n", selector); + + return false; + } + + TU_LOG_USBD(" Schedule Test Mode (test selector index: %d)\r\n", selector); + + // Acknowledge request + tud_control_status(rhport, p_request); + + // Schedule the execution of the test mode so that the request can be answered + dcd_event_enter_test_mode(rhport, selector, false); + + break; + + // Stall unsupported feature selector + default: return false; + } break; case TUSB_REQ_CLEAR_FEATURE: diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index c6132a1f5..ee4b2b28d 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1351,4 +1351,34 @@ void dcd_int_handler(uint8_t rhport) // } } +#if defined(TUP_USBIP_DWC2_TEST_MODE_SUPPORT) + +bool dcd_test_mode_supported(test_mode_t test_selector) { + // Check if test mode selector is unsupported + if (TEST_FORCE_ENABLE < test_selector || TEST_J > test_selector) { + return false; + } + + return true; +} + +void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) { + // Disable test mode if not supported + if (!dcd_test_mode_supported(test_selector)) { + test_selector = 0; + } + + // Delay the entering a bit so there is enough time to acknowledge request + uint32_t count = SystemCoreClock / 20000; + while (count--) __NOP(); + + // Get port address... + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + + // Enable the test mode + dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (test_selector << DCTL_TCTL_Pos); +} + +#endif /* TUP_USBIP_DWC2_TEST_MODE_SUPPORT */ + #endif -- cgit v1.3.1 From c3e96e667f45e695bc855db4011f1a7f46d24b29 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Mon, 15 Jan 2024 15:10:46 +0000 Subject: Change to control complete cb --- src/device/dcd.h | 19 +++---------------- src/device/usbd.c | 34 ++++++++++++++++++---------------- src/portable/synopsys/dwc2/dcd_dwc2.c | 11 +++-------- 3 files changed, 24 insertions(+), 40 deletions(-) diff --git a/src/device/dcd.h b/src/device/dcd.h index 7755ef107..2248cd392 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -58,7 +58,6 @@ typedef enum DCD_EVENT_SETUP_RECEIVED, DCD_EVENT_XFER_COMPLETE, - DCD_EVENT_TEST_MODE, // Not an DCD event, just a convenient way to defer ISR function USBD_EVENT_FUNC_CALL, @@ -71,7 +70,7 @@ typedef struct TU_ATTR_ALIGNED(4) uint8_t rhport; uint8_t event_id; - union + union { // BUS RESET struct { @@ -98,11 +97,6 @@ typedef struct TU_ATTR_ALIGNED(4) void (*func) (void*); void* param; }func_call; - - // TEST MODE - struct { - uint8_t selector; - }test_mode; }; } dcd_event_t; @@ -164,8 +158,8 @@ void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK; // Enable/Disable Start-of-frame interrupt. Default is disabled void dcd_sof_enable(uint8_t rhport, bool en); -// Check if the test mode is supported -bool dcd_test_mode_supported(test_mode_t test_selector) TU_ATTR_WEAK; +// Check if the test mode is supported, returns true is test mode selector is supported +bool dcd_check_test_mode_support(test_mode_t test_selector) TU_ATTR_WEAK; // Put device into a test mode (needs power cycle to quit) void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) TU_ATTR_WEAK; @@ -261,13 +255,6 @@ static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_i dcd_event_handler(&event, in_isr); } -TU_ATTR_ALWAYS_INLINE static inline void dcd_event_enter_test_mode(uint8_t rhport, uint8_t test_selector, bool in_isr) -{ - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_TEST_MODE }; - event.test_mode.selector = test_selector; - dcd_event_handler(&event, in_isr); -} - #ifdef __cplusplus } #endif diff --git a/src/device/usbd.c b/src/device/usbd.c index 90fde92b5..fbdba4d2f 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -285,6 +285,7 @@ tu_static osal_queue_t _usbd_q; static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request); static bool process_set_config(uint8_t rhport, uint8_t cfg_num); static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request); +static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); // from usbd_control.c void usbd_control_reset(void); @@ -587,11 +588,6 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) if ( event.func_call.func ) event.func_call.func(event.func_call.param); break; - case DCD_EVENT_TEST_MODE: - TU_LOG_USBD(": Enter Test Mode with selector index = %d)\r\n", event.test_mode.selector); - if (dcd_enter_test_mode) dcd_enter_test_mode(event.rhport, event.test_mode.selector); - break; - case DCD_EVENT_SOF: default: TU_BREAKPOINT(); @@ -740,35 +736,29 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // Host may enable remote wake up before suspending especially HID device _usbd_dev.remote_wakeup_en = true; tud_control_status(rhport, p_request); - break; // Support for TEST_MODE case TUSB_REQ_FEATURE_TEST_MODE: - // Only handle the test mode is supported and valid - if (!dcd_enter_test_mode || !dcd_test_mode_supported || 0 != tu_u16_low(p_request->wIndex)) - { - return false; - } + // Only handle the test mode if supported and valid + TU_VERIFY(dcd_enter_test_mode && dcd_check_test_mode_support && 0 == tu_u16_low(p_request->wIndex)); uint8_t selector = tu_u16_high(p_request->wIndex); // Stall request if the selected test mode isn't supported - if (!dcd_test_mode_supported(selector)) + if (!dcd_check_test_mode_support(selector)) { TU_LOG_USBD(" Unsupported Test Mode (test selector index: %d)\r\n", selector); return false; } - TU_LOG_USBD(" Schedule Test Mode (test selector index: %d)\r\n", selector); - // Acknowledge request tud_control_status(rhport, p_request); - // Schedule the execution of the test mode so that the request can be answered - dcd_event_enter_test_mode(rhport, selector, false); + TU_LOG_USBD(" Enter Test Mode (test selector index: %d)\r\n", selector); + usbd_control_set_complete_callback(process_test_mode_cb); break; // Stall unsupported feature selector @@ -1115,6 +1105,18 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const } } +bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + // At this point it should already be ensured that dcd_enter_test_mode() is defined + + // Only enter the test mode after the request for it has completed + TU_VERIFY(CONTROL_STAGE_ACK == stage); + + dcd_enter_test_mode(rhport, tu_u16_high(request->wIndex)); + + return true; +} + //--------------------------------------------------------------------+ // DCD Event Handler //--------------------------------------------------------------------+ diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index ee4b2b28d..aa4a8bfb2 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1353,7 +1353,7 @@ void dcd_int_handler(uint8_t rhport) #if defined(TUP_USBIP_DWC2_TEST_MODE_SUPPORT) -bool dcd_test_mode_supported(test_mode_t test_selector) { +bool dcd_check_test_mode_support(test_mode_t test_selector) { // Check if test mode selector is unsupported if (TEST_FORCE_ENABLE < test_selector || TEST_J > test_selector) { return false; @@ -1363,15 +1363,10 @@ bool dcd_test_mode_supported(test_mode_t test_selector) { } void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) { - // Disable test mode if not supported - if (!dcd_test_mode_supported(test_selector)) { + // Disable test mode if not supported as a fall back + if (!dcd_check_test_mode_support(test_selector)) { test_selector = 0; } - - // Delay the entering a bit so there is enough time to acknowledge request - uint32_t count = SystemCoreClock / 20000; - while (count--) __NOP(); - // Get port address... dwc2_regs_t* dwc2 = DWC2_REG(rhport); -- cgit v1.3.1 From 3c4184dc15fad3eccf53c247a1c8de56bd4bd517 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Mon, 15 Jan 2024 16:16:09 +0100 Subject: Removed whitespace --- src/device/dcd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/dcd.h b/src/device/dcd.h index 2248cd392..8a890cec3 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -70,7 +70,7 @@ typedef struct TU_ATTR_ALIGNED(4) uint8_t rhport; uint8_t event_id; - union + union { // BUS RESET struct { -- cgit v1.3.1 From 783a4f002b3c876aef6077ea57d0060b072e8ca9 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Mon, 15 Jan 2024 16:45:58 +0100 Subject: Test mode support only for Hi-Speed devices --- src/common/tusb_mcu.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index d74d7a2c5..ef28ac8fb 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -195,7 +195,6 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32F7) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 - #define TUP_USBIP_DWC2_TEST_MODE_SUPPORT // FS has 6, HS has 9 #define TUP_DCD_ENDPOINT_MAX 9 @@ -203,6 +202,7 @@ // MCU with on-chip HS Phy #if defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F733xx) #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS + #define TUP_USBIP_DWC2_TEST_MODE_SUPPORT #endif #elif TU_CHECK_MCU(OPT_MCU_STM32H7) @@ -265,13 +265,13 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32U5) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 - #define TUP_USBIP_DWC2_TEST_MODE_SUPPORT // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #if defined(STM32U595xx) || defined(STM32U599xx) || defined(STM32U5A5xx) || defined(STM32U5A9xx) || \ defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) #define TUP_DCD_ENDPOINT_MAX 9 #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_USBIP_DWC2_TEST_MODE_SUPPORT #else #define TUP_DCD_ENDPOINT_MAX 6 #endif -- cgit v1.3.1 From e0ebece2c76a77457ea67d66065d08750ae77eaa Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Mon, 15 Jan 2024 18:23:59 +0100 Subject: Missed static keyword --- src/device/usbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 661ba95a3..83217a869 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1098,7 +1098,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const } } -bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { // At this point it should already be ensured that dcd_enter_test_mode() is defined -- cgit v1.3.1 From 297290c16da3a0f897197492e94717acc17c0c70 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 1 Feb 2024 13:11:56 +0100 Subject: Allow vendor class to be used without FIFO. --- src/class/vendor/vendor_device.c | 73 +++++++++++++++++++++++++++++++++++----- src/class/vendor/vendor_device.h | 34 +++++++++++++++---- 2 files changed, 91 insertions(+), 16 deletions(-) diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index a68cb2156..12b3e237c 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -43,14 +43,26 @@ typedef struct uint8_t ep_out; /*------------- From this point, data is not cleared by bus reset -------------*/ +#if CFG_TUD_VENDOR_USE_RX_FIFO tu_fifo_t rx_ff; +#endif +#if CFG_TUD_VENDOR_USE_TX_FIFO tu_fifo_t tx_ff; +#endif +#if CFG_TUD_VENDOR_USE_RX_FIFO uint8_t rx_ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; +#endif +#if CFG_TUD_VENDOR_USE_TX_FIFO uint8_t tx_ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; +#endif +#if CFG_TUD_VENDOR_USE_RX_FIFO OSAL_MUTEX_DEF(rx_ff_mutex); +#endif +#if CFG_TUD_VENDOR_USE_TX_FIFO OSAL_MUTEX_DEF(tx_ff_mutex); +#endif // Endpoint Transfer buffer CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_VENDOR_EPSIZE]; @@ -59,7 +71,7 @@ typedef struct CFG_TUD_MEM_SECTION tu_static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; -#define ITF_MEM_RESET_SIZE offsetof(vendord_interface_t, rx_ff) +#define ITF_MEM_RESET_SIZE offsetof(vendord_interface_t, ep_out) + sizeof(((vendord_interface_t *)0)->ep_out) bool tud_vendor_n_mounted (uint8_t itf) @@ -67,6 +79,7 @@ bool tud_vendor_n_mounted (uint8_t itf) return _vendord_itf[itf].ep_in && _vendord_itf[itf].ep_out; } +#if CFG_TUD_VENDOR_USE_RX_FIFO uint32_t tud_vendor_n_available (uint8_t itf) { return tu_fifo_count(&_vendord_itf[itf].rx_ff); @@ -76,10 +89,12 @@ bool tud_vendor_n_peek(uint8_t itf, uint8_t* u8) { return tu_fifo_peek(&_vendord_itf[itf].rx_ff, u8); } +#endif //--------------------------------------------------------------------+ // Read API //--------------------------------------------------------------------+ +#if CFG_TUD_VENDOR_USE_RX_FIFO static void _prep_out_transaction (vendord_interface_t* p_itf) { uint8_t const rhport = 0; @@ -114,12 +129,14 @@ void tud_vendor_n_read_flush (uint8_t itf) tu_fifo_clear(&p_itf->rx_ff); _prep_out_transaction(p_itf); } +#endif //--------------------------------------------------------------------+ // Write API //--------------------------------------------------------------------+ uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) { +#if CFG_TUD_VENDOR_USE_TX_FIFO vendord_interface_t* p_itf = &_vendord_itf[itf]; uint16_t ret = tu_fifo_write_n(&p_itf->tx_ff, buffer, (uint16_t) bufsize); @@ -128,8 +145,23 @@ uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) tud_vendor_n_write_flush(itf); } return ret; +#else + uint8_t const rhport = 0; + vendord_interface_t* p_itf = &_vendord_itf[itf]; + + // claim endpoint + TU_VERIFY(usbd_edpt_claim(rhport, p_itf->ep_in)); + + // prepare data + TU_VERIFY(0 == tu_memcpy_s(p_itf->epin_buf, CFG_TUD_VENDOR_EPSIZE, buffer, (uint16_t) bufsize)); + + TU_ASSERT(usbd_edpt_xfer(rhport, p_itf->ep_in, p_itf->epin_buf, (uint16_t) bufsize)); + + return bufsize; +#endif } +#if CFG_TUD_VENDOR_USE_TX_FIFO uint32_t tud_vendor_n_write_flush (uint8_t itf) { vendord_interface_t* p_itf = &_vendord_itf[itf]; @@ -165,6 +197,7 @@ uint32_t tud_vendor_n_write_available (uint8_t itf) { return tu_fifo_remaining(&_vendord_itf[itf].tx_ff); } +#endif //--------------------------------------------------------------------+ // USBD Driver API @@ -175,14 +208,18 @@ void vendord_init(void) for(uint8_t i=0; irx_ff, p_itf->rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, 1, false); - tu_fifo_config(&p_itf->tx_ff, p_itf->tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, 1, false); - tu_fifo_config_mutex(&p_itf->rx_ff, NULL, osal_mutex_create(&p_itf->rx_ff_mutex)); +#endif +#if CFG_TUD_VENDOR_USE_TX_FIFO + tu_fifo_config(&p_itf->tx_ff, p_itf->tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, 1, false); tu_fifo_config_mutex(&p_itf->tx_ff, osal_mutex_create(&p_itf->tx_ff_mutex), NULL); +#endif } } @@ -195,8 +232,12 @@ void vendord_reset(uint8_t rhport) vendord_interface_t* p_itf = &_vendord_itf[i]; tu_memclr(p_itf, ITF_MEM_RESET_SIZE); +#if CFG_TUD_VENDOR_USE_RX_FIFO tu_fifo_clear(&p_itf->rx_ff); +#endif +#if CFG_TUD_VENDOR_USE_TX_FIFO tu_fifo_clear(&p_itf->tx_ff); +#endif } } @@ -234,12 +275,19 @@ uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, ui p_desc += desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); // Prepare for incoming data - if ( p_vendor->ep_out ) +#if CFG_TUD_VENDOR_USE_RX_FIFO + _prep_out_transaction(p_vendor); +#else + if ( !usbd_edpt_xfer(rhport, p_vendor->ep_out, p_vendor->epout_buf, CFG_TUD_VENDOR_EPSIZE) ) { - _prep_out_transaction(p_vendor); + TU_LOG_FAILED(); + TU_BREAKPOINT(); } +#endif - if ( p_vendor->ep_in ) tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf)); +#if CFG_TUD_VENDOR_USE_TX_FIFO + tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf)); +#endif } return (uint16_t) ((uintptr_t) p_desc - (uintptr_t) desc_itf); @@ -262,19 +310,26 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint if ( ep_addr == p_itf->ep_out ) { +#if CFG_TUD_VENDOR_USE_RX_FIFO // Receive new data tu_fifo_write_n(&p_itf->rx_ff, p_itf->epout_buf, (uint16_t) xferred_bytes); +#endif // Invoked callback if any - if (tud_vendor_rx_cb) tud_vendor_rx_cb(itf); - + if (tud_vendor_rx_cb) tud_vendor_rx_cb(itf, p_itf->epout_buf, (uint16_t) xferred_bytes); +#if CFG_TUD_VENDOR_USE_RX_FIFO _prep_out_transaction(p_itf); +#else + TU_ASSERT(usbd_edpt_xfer(rhport, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE)); +#endif } else if ( ep_addr == p_itf->ep_in ) { if (tud_vendor_tx_cb) tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); +#if CFG_TUD_VENDOR_USE_TX_FIFO // Send complete, try to send more if possible tud_vendor_n_write_flush(itf); +#endif } return true; diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index d239406b4..aabce5357 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -33,6 +33,14 @@ #define CFG_TUD_VENDOR_EPSIZE 64 #endif +#ifndef CFG_TUD_VENDOR_USE_RX_FIFO +#define CFG_TUD_VENDOR_USE_RX_FIFO 1 +#endif + +#ifndef CFG_TUD_VENDOR_USE_TX_FIFO +#define CFG_TUD_VENDOR_USE_TX_FIFO 1 +#endif + #ifdef __cplusplus extern "C" { #endif @@ -42,42 +50,50 @@ //--------------------------------------------------------------------+ bool tud_vendor_n_mounted (uint8_t itf); +#if CFG_TUD_VENDOR_USE_RX_FIFO uint32_t tud_vendor_n_available (uint8_t itf); uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize); bool tud_vendor_n_peek (uint8_t itf, uint8_t* ui8); void tud_vendor_n_read_flush (uint8_t itf); +#endif uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); +#if CFG_TUD_VENDOR_USE_TX_FIFO uint32_t tud_vendor_n_write_flush (uint8_t itf); uint32_t tud_vendor_n_write_available (uint8_t itf); - +#endif static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); +#if CFG_TUD_VENDOR_USE_TX_FIFO // backward compatible #define tud_vendor_n_flush(itf) tud_vendor_n_write_flush(itf) +#endif //--------------------------------------------------------------------+ // Application API (Single Port) //--------------------------------------------------------------------+ static inline bool tud_vendor_mounted (void); +#if CFG_TUD_VENDOR_USE_RX_FIFO static inline uint32_t tud_vendor_available (void); static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize); static inline bool tud_vendor_peek (uint8_t* ui8); static inline void tud_vendor_read_flush (void); +#endif static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize); static inline uint32_t tud_vendor_write_str (char const* str); +#if CFG_TUD_VENDOR_USE_TX_FIFO static inline uint32_t tud_vendor_write_available (void); static inline uint32_t tud_vendor_write_flush (void); // backward compatible #define tud_vendor_flush() tud_vendor_write_flush() - +#endif //--------------------------------------------------------------------+ // Application Callback API (weak is optional) //--------------------------------------------------------------------+ // Invoked when received new data -TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t itf); +TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t itf, uint8_t const* buffer, uint16_t bufsize); // Invoked when last rx transfer finished TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes); @@ -95,6 +111,7 @@ static inline bool tud_vendor_mounted (void) return tud_vendor_n_mounted(0); } +#if CFG_TUD_VENDOR_USE_RX_FIFO static inline uint32_t tud_vendor_available (void) { return tud_vendor_n_available(0); @@ -114,26 +131,29 @@ static inline void tud_vendor_read_flush(void) { tud_vendor_n_read_flush(0); } +#endif static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize) { return tud_vendor_n_write(0, buffer, bufsize); } -static inline uint32_t tud_vendor_write_flush (void) +static inline uint32_t tud_vendor_write_str (char const* str) { - return tud_vendor_n_write_flush(0); + return tud_vendor_n_write_str(0, str); } -static inline uint32_t tud_vendor_write_str (char const* str) +#if CFG_TUD_VENDOR_USE_TX_FIFO +static inline uint32_t tud_vendor_write_flush (void) { - return tud_vendor_n_write_str(0, str); + return tud_vendor_n_write_flush(0); } static inline uint32_t tud_vendor_write_available (void) { return tud_vendor_n_write_available(0); } +#endif //--------------------------------------------------------------------+ // Internal Class Driver API -- cgit v1.3.1 From d0373f4749e320c7cb3fac9cce068b4398e60f2f Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Mon, 19 Feb 2024 17:44:18 +0000 Subject: Opt-out for USB Test-Mode --- src/device/usbd.c | 4 ++++ src/portable/synopsys/dwc2/dcd_dwc2.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 83217a869..1da6f0b53 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -731,6 +731,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const tud_control_status(rhport, p_request); break; + #if !defined(TUSB_NO_TEST_MODE_SUPPORT) // Support for TEST_MODE case TUSB_REQ_FEATURE_TEST_MODE: // Only handle the test mode if supported and valid @@ -753,6 +754,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const usbd_control_set_complete_callback(process_test_mode_cb); break; + #endif /* !TUSB_NO_TEST_MODE_SUPPORT */ // Stall unsupported feature selector default: return false; @@ -1098,6 +1100,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const } } +#if !defined(TUSB_NO_TEST_MODE_SUPPORT) static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { // At this point it should already be ensured that dcd_enter_test_mode() is defined @@ -1109,6 +1112,7 @@ static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_req return true; } +#endif /* !TUSB_NO_TEST_MODE_SUPPORT */ //--------------------------------------------------------------------+ // DCD Event Handler diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 381aeca71..8163ba8e1 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1186,7 +1186,7 @@ void dcd_int_handler(uint8_t rhport) { // } } -#if defined(TUP_USBIP_DWC2_TEST_MODE_SUPPORT) +#if defined(TUP_USBIP_DWC2_TEST_MODE_SUPPORT) && !defined(TUSB_NO_TEST_MODE_SUPPORT) bool dcd_check_test_mode_support(test_mode_t test_selector) { // Check if test mode selector is unsupported @@ -1209,6 +1209,6 @@ void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) { dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (test_selector << DCTL_TCTL_Pos); } -#endif /* TUP_USBIP_DWC2_TEST_MODE_SUPPORT */ +#endif /* TUP_USBIP_DWC2_TEST_MODE_SUPPORT && !TUSB_NO_TEST_MODE_SUPPORT */ #endif -- cgit v1.3.1 From 5ce7b147117826dd75c2d7b347df80b0177e7252 Mon Sep 17 00:00:00 2001 From: Tommie Gannert Date: Mon, 26 Feb 2024 11:41:50 +0100 Subject: add notification support for device class USBTMC. The ep_int_in is already used for responding to USB488 READ_STATUS_BYTE requests, but that EP is defined for all of USBTMC. This extends the functionality to let callers send notifications and receive ACKs. --- src/class/usbtmc/usbtmc.h | 25 +++++++++++++++++++++++++ src/class/usbtmc/usbtmc_device.c | 16 +++++++++++++++- src/class/usbtmc/usbtmc_device.h | 20 +++++++++++++++----- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/class/usbtmc/usbtmc.h b/src/class/usbtmc/usbtmc.h index 090ab3c4a..327de087c 100644 --- a/src/class/usbtmc/usbtmc.h +++ b/src/class/usbtmc/usbtmc.h @@ -183,6 +183,23 @@ typedef enum { } usmtmc_request_type_enum; +typedef enum { + // The last and first valid bNotify1 for use by the USBTMC class specification. + USBTMC_bNOTIFY1_USBTMC_FIRST = 0x00, + USBTMC_bNOTIFY1_USBTMC_LAST = 0x3F, + + // The last and first valid bNotify1 for use by vendors. + USBTMC_bNOTIFY1_VENDOR_SPECIFIC_FIRST = 0x40, + USBTMC_bNOTIFY1_VENDOR_SPECIFIC_LAST = 0x7F, + + // The last and first valid bNotify1 for use by USBTMC subclass specifications. + USBTMC_bNOTIFY1_SUBCLASS_FIRST = 0x80, + USBTMC_bNOTIFY1_SUBCLASS_LAST = 0xFF, + + // From the USB488 Subclass Specification, Section 3.4. + USB488_bNOTIFY1_SRQ = 0x81, +} usbtmc_int_in_payload_format; + typedef enum { USBTMC_STATUS_SUCCESS = 0x01, USBTMC_STATUS_PENDING = 0x02, @@ -303,6 +320,14 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_rsp_488_t) == 3u, "struct wrong length"); +typedef struct TU_ATTR_PACKED +{ + uint8_t bNotify1; // Must be USB488_bNOTIFY1_SRQ + uint8_t StatusByte; +} usbtmc_srq_interrupt_488_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_srq_interrupt_488_t) == 2u, "struct wrong length"); + typedef struct TU_ATTR_PACKED { struct TU_ATTR_PACKED diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 573654d58..debe445fd 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -240,6 +240,18 @@ bool tud_usbtmc_transmit_dev_msg_data( return true; } +bool tud_usbtmc_transmit_notification_data(const void * data, size_t len) +{ +#ifndef NDEBUG + TU_ASSERT(len >= 1); + TU_ASSERT(usbtmc_state.ep_int_in != 0); +#endif + if (usbd_edpt_busy(usbtmc_state.rhport, usbtmc_state.ep_int_in)) return false; + + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, (void *)data, len)); + return true; +} + void usbtmcd_init_cb(void) { usbtmc_state.capabilities = tud_usbtmc_get_capabilities_cb(); @@ -578,7 +590,9 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint } } else if (ep_addr == usbtmc_state.ep_int_in) { - // Good? + if (tud_usbtmc_notification_complete_cb) { + TU_VERIFY(tud_usbtmc_notification_complete_cb()); + } return true; } return false; diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index c1298ddb8..2f3c91dbd 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -73,6 +73,10 @@ bool tud_usbtmc_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp); bool tud_usbtmc_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp); bool tud_usbtmc_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp); +// The interrupt-IN endpoint buffer was transmitted to the host. Use +// tud_usbtmc_transmit_notification_data to send another notification. +TU_ATTR_WEAK bool tud_usbtmc_notification_complete_cb(void); + // Indicator pulse should be 0.5 to 1.0 seconds long TU_ATTR_WEAK bool tud_usbtmc_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult); @@ -93,6 +97,17 @@ bool tud_usbtmc_transmit_dev_msg_data( const void * data, size_t len, bool endOfMessage, bool usingTermChar); +// Buffers a notification to be sent to the host. The buffer must be +// valid until the tud_usbtmc_notification_complete_cb callback. The +// data starts with the bNotify1 field, see the USBTMC Specification, +// Table 13. +// +// If the previous notification data has not yet been sent, this +// returns false. +// +// Requires an interrupt endpoint in the interface. +bool tud_usbtmc_transmit_notification_data(const void * data, size_t len); + bool tud_usbtmc_start_bus_read(void); @@ -104,9 +119,4 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); void usbtmcd_init_cb(void); -/************************************************************ - * USBTMC Descriptor Templates - *************************************************************/ - - #endif /* CLASS_USBTMC_USBTMC_DEVICE_H_ */ -- cgit v1.3.1 From 5c8b3d97f04443f386270eba6171af9a333855c6 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 3 Mar 2024 20:11:20 +0100 Subject: Use FIFO size as condition. --- src/class/vendor/vendor_device.c | 40 ++++++++++++++++++++-------------------- src/class/vendor/vendor_device.h | 24 +++++++++++++----------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 12b3e237c..fe746eda0 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -43,24 +43,24 @@ typedef struct uint8_t ep_out; /*------------- From this point, data is not cleared by bus reset -------------*/ -#if CFG_TUD_VENDOR_USE_RX_FIFO +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 tu_fifo_t rx_ff; #endif -#if CFG_TUD_VENDOR_USE_TX_FIFO +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 tu_fifo_t tx_ff; #endif -#if CFG_TUD_VENDOR_USE_RX_FIFO +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 uint8_t rx_ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; #endif -#if CFG_TUD_VENDOR_USE_TX_FIFO +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 uint8_t tx_ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; #endif -#if CFG_TUD_VENDOR_USE_RX_FIFO +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 OSAL_MUTEX_DEF(rx_ff_mutex); #endif -#if CFG_TUD_VENDOR_USE_TX_FIFO +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 OSAL_MUTEX_DEF(tx_ff_mutex); #endif @@ -79,7 +79,7 @@ bool tud_vendor_n_mounted (uint8_t itf) return _vendord_itf[itf].ep_in && _vendord_itf[itf].ep_out; } -#if CFG_TUD_VENDOR_USE_RX_FIFO +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 uint32_t tud_vendor_n_available (uint8_t itf) { return tu_fifo_count(&_vendord_itf[itf].rx_ff); @@ -94,7 +94,7 @@ bool tud_vendor_n_peek(uint8_t itf, uint8_t* u8) //--------------------------------------------------------------------+ // Read API //--------------------------------------------------------------------+ -#if CFG_TUD_VENDOR_USE_RX_FIFO +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 static void _prep_out_transaction (vendord_interface_t* p_itf) { uint8_t const rhport = 0; @@ -136,7 +136,7 @@ void tud_vendor_n_read_flush (uint8_t itf) //--------------------------------------------------------------------+ uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) { -#if CFG_TUD_VENDOR_USE_TX_FIFO +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 vendord_interface_t* p_itf = &_vendord_itf[itf]; uint16_t ret = tu_fifo_write_n(&p_itf->tx_ff, buffer, (uint16_t) bufsize); @@ -161,7 +161,7 @@ uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) #endif } -#if CFG_TUD_VENDOR_USE_TX_FIFO +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 uint32_t tud_vendor_n_write_flush (uint8_t itf) { vendord_interface_t* p_itf = &_vendord_itf[itf]; @@ -208,15 +208,15 @@ void vendord_init(void) for(uint8_t i=0; i 0 || CFG_TUD_VENDOR_TX_BUFSIZE > 0 vendord_interface_t* p_itf = &_vendord_itf[i]; #endif // config fifo -#if CFG_TUD_VENDOR_USE_RX_FIFO +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 tu_fifo_config(&p_itf->rx_ff, p_itf->rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, 1, false); tu_fifo_config_mutex(&p_itf->rx_ff, NULL, osal_mutex_create(&p_itf->rx_ff_mutex)); #endif -#if CFG_TUD_VENDOR_USE_TX_FIFO +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 tu_fifo_config(&p_itf->tx_ff, p_itf->tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, 1, false); tu_fifo_config_mutex(&p_itf->tx_ff, osal_mutex_create(&p_itf->tx_ff_mutex), NULL); #endif @@ -232,10 +232,10 @@ void vendord_reset(uint8_t rhport) vendord_interface_t* p_itf = &_vendord_itf[i]; tu_memclr(p_itf, ITF_MEM_RESET_SIZE); -#if CFG_TUD_VENDOR_USE_RX_FIFO +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 tu_fifo_clear(&p_itf->rx_ff); #endif -#if CFG_TUD_VENDOR_USE_TX_FIFO +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 tu_fifo_clear(&p_itf->tx_ff); #endif } @@ -275,7 +275,7 @@ uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, ui p_desc += desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); // Prepare for incoming data -#if CFG_TUD_VENDOR_USE_RX_FIFO +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 _prep_out_transaction(p_vendor); #else if ( !usbd_edpt_xfer(rhport, p_vendor->ep_out, p_vendor->epout_buf, CFG_TUD_VENDOR_EPSIZE) ) @@ -285,7 +285,7 @@ uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, ui } #endif -#if CFG_TUD_VENDOR_USE_TX_FIFO +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf)); #endif } @@ -310,14 +310,14 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint if ( ep_addr == p_itf->ep_out ) { -#if CFG_TUD_VENDOR_USE_RX_FIFO +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 // Receive new data tu_fifo_write_n(&p_itf->rx_ff, p_itf->epout_buf, (uint16_t) xferred_bytes); #endif // Invoked callback if any if (tud_vendor_rx_cb) tud_vendor_rx_cb(itf, p_itf->epout_buf, (uint16_t) xferred_bytes); -#if CFG_TUD_VENDOR_USE_RX_FIFO +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 _prep_out_transaction(p_itf); #else TU_ASSERT(usbd_edpt_xfer(rhport, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE)); @@ -326,7 +326,7 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint else if ( ep_addr == p_itf->ep_in ) { if (tud_vendor_tx_cb) tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); -#if CFG_TUD_VENDOR_USE_TX_FIFO +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 // Send complete, try to send more if possible tud_vendor_n_write_flush(itf); #endif diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index aabce5357..1e973b153 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -33,12 +33,14 @@ #define CFG_TUD_VENDOR_EPSIZE 64 #endif -#ifndef CFG_TUD_VENDOR_USE_RX_FIFO -#define CFG_TUD_VENDOR_USE_RX_FIFO 1 +/* RX FIFO can be disabled by setting this value to 0, related API will also be disabled */ +#ifndef CFG_TUD_VENDOR_RX_BUFSIZE +#define CFG_TUD_VENDOR_RX_BUFSIZE 64 #endif -#ifndef CFG_TUD_VENDOR_USE_TX_FIFO -#define CFG_TUD_VENDOR_USE_TX_FIFO 1 +/* TX FIFO can be disabled by setting this value to 0, related API will also be disabled */ +#ifndef CFG_TUD_VENDOR_TX_BUFSIZE +#define CFG_TUD_VENDOR_TX_BUFSIZE 64 #endif #ifdef __cplusplus @@ -50,7 +52,7 @@ //--------------------------------------------------------------------+ bool tud_vendor_n_mounted (uint8_t itf); -#if CFG_TUD_VENDOR_USE_RX_FIFO +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 uint32_t tud_vendor_n_available (uint8_t itf); uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize); bool tud_vendor_n_peek (uint8_t itf, uint8_t* ui8); @@ -58,13 +60,13 @@ void tud_vendor_n_read_flush (uint8_t itf); #endif uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); -#if CFG_TUD_VENDOR_USE_TX_FIFO +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 uint32_t tud_vendor_n_write_flush (uint8_t itf); uint32_t tud_vendor_n_write_available (uint8_t itf); #endif static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); -#if CFG_TUD_VENDOR_USE_TX_FIFO +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 // backward compatible #define tud_vendor_n_flush(itf) tud_vendor_n_write_flush(itf) #endif @@ -73,7 +75,7 @@ static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); // Application API (Single Port) //--------------------------------------------------------------------+ static inline bool tud_vendor_mounted (void); -#if CFG_TUD_VENDOR_USE_RX_FIFO +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 static inline uint32_t tud_vendor_available (void); static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize); static inline bool tud_vendor_peek (uint8_t* ui8); @@ -81,7 +83,7 @@ static inline void tud_vendor_read_flush (void); #endif static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize); static inline uint32_t tud_vendor_write_str (char const* str); -#if CFG_TUD_VENDOR_USE_TX_FIFO +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 static inline uint32_t tud_vendor_write_available (void); static inline uint32_t tud_vendor_write_flush (void); @@ -111,7 +113,7 @@ static inline bool tud_vendor_mounted (void) return tud_vendor_n_mounted(0); } -#if CFG_TUD_VENDOR_USE_RX_FIFO +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 static inline uint32_t tud_vendor_available (void) { return tud_vendor_n_available(0); @@ -143,7 +145,7 @@ static inline uint32_t tud_vendor_write_str (char const* str) return tud_vendor_n_write_str(0, str); } -#if CFG_TUD_VENDOR_USE_TX_FIFO +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 static inline uint32_t tud_vendor_write_flush (void) { return tud_vendor_n_write_flush(0); -- cgit v1.3.1 From 9e674fa109348d97fb4280ac534be665f619a4d8 Mon Sep 17 00:00:00 2001 From: Tommie Gannert Date: Fri, 15 Mar 2024 15:02:13 +0100 Subject: [usbtmc] cast to uintptr_t to get rid of const for usbd_edpt_xfer. --- src/class/usbtmc/usbtmc_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index debe445fd..4092c37ea 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -248,7 +248,7 @@ bool tud_usbtmc_transmit_notification_data(const void * data, size_t len) #endif if (usbd_edpt_busy(usbtmc_state.rhport, usbtmc_state.ep_int_in)) return false; - TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, (void *)data, len)); + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, (void *)(uintptr_t) data, len)); return true; } -- cgit v1.3.1 From c8805c61f9b0e3c03d8d3592127b1239a45c9880 Mon Sep 17 00:00:00 2001 From: acscd Date: Fri, 22 Mar 2024 20:05:52 -0500 Subject: Add files via upload --- src/class/msc/msc_device.c | 18 ++++++++++++++++++ src/class/msc/msc_device.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index c145d86a6..19e97a50f 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -685,6 +685,24 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ } break; + case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: + resplen = 0; + + if (tud_msc_prevent_allow_medium_removal_cb) + { + scsi_prevent_allow_medium_removal_t const * prevent_allow = (scsi_prevent_allow_medium_removal_t const *) scsi_cmd; + if ( !tud_msc_prevent_allow_medium_removal_cb(lun, prevent_allow->prohibit_removal, prevent_allow->control) ) + { + // Failed status response + resplen = - 1; + + // set default sense if not set by callback + if ( p_msc->sense_key == 0 ) set_sense_medium_not_present(lun); + } + } + break; + + case SCSI_CMD_READ_CAPACITY_10: { uint32_t block_count; diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h index 72f95be06..c4632b4b7 100644 --- a/src/class/msc/msc_device.h +++ b/src/class/msc/msc_device.h @@ -131,6 +131,9 @@ TU_ATTR_WEAK uint8_t tud_msc_get_maxlun_cb(void); // - Start = 1 : active mode, if load_eject = 1 : load disk storage TU_ATTR_WEAK bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject); +//Invoked when we receive the Prevent / Allow Medium Removal command +TU_ATTR_WEAK bool tud_msc_prevent_allow_medium_removal_cb(uint8_t lun, uint8_t prohibit_removal, uint8_t control); + // Invoked when received REQUEST_SENSE TU_ATTR_WEAK int32_t tud_msc_request_sense_cb(uint8_t lun, void* buffer, uint16_t bufsize); -- cgit v1.3.1 From 7a3e730dedad4d75f901d3c5ac393e001de69157 Mon Sep 17 00:00:00 2001 From: tyustli <43946994+tyustli@users.noreply.github.com> Date: Wed, 24 Apr 2024 21:44:03 +0800 Subject: Remove redundant header file includes for the hid class --- src/tusb.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tusb.h b/src/tusb.h index c9d56d3c3..4f69a1414 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -38,8 +38,6 @@ #include "osal/osal.h" #include "common/tusb_fifo.h" -#include "class/hid/hid.h" - //------------- TypeC -------------// #if CFG_TUC_ENABLED #include "typec/usbc.h" -- cgit v1.3.1 From 1e7091dae98ea3eeba4789364c290199b157c368 Mon Sep 17 00:00:00 2001 From: tyustli <43946994+tyustli@users.noreply.github.com> Date: Thu, 25 Apr 2024 19:47:12 +0800 Subject: fix ci error --- examples/host/bare_api/src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 14725996d..b1d388bf9 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -34,6 +34,7 @@ #include "bsp/board_api.h" #include "tusb.h" +#include "class/hid/hid.h" // English #define LANGUAGE_ID 0x0409 -- cgit v1.3.1 From 2e995d7cf4b2971e3ca7167a097b99832c8d61ce Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Apr 2024 20:23:40 +0700 Subject: adding support for esp32 for use with max3421e host --- examples/device/board_test/src/tusb_config.h | 2 +- examples/device/cdc_msc_freertos/src/main.c | 6 +-- examples/device/cdc_msc_freertos/src/tusb_config.h | 2 +- examples/device/hid_composite_freertos/src/main.c | 6 +-- .../hid_composite_freertos/src/tusb_config.h | 2 +- examples/device/video_capture/src/main.c | 4 +- examples/device/video_capture/src/tusb_config.h | 2 +- examples/device/video_capture_2ch/src/main.c | 4 +- .../device/video_capture_2ch/src/tusb_config.h | 2 +- examples/host/cdc_msc_hid_freertos/src/cdc_app.c | 2 +- examples/host/cdc_msc_hid_freertos/src/main.c | 6 +-- .../host/cdc_msc_hid_freertos/src/tusb_config.h | 2 +- hw/bsp/board_api.h | 2 +- .../boards/adafruit_feather_esp32_v2/board.cmake | 2 + .../boards/adafruit_feather_esp32_v2/board.h | 53 ++++++++++++++++++++++ hw/bsp/espressif/boards/family.c | 19 ++++---- .../components/tinyusb_src/CMakeLists.txt | 12 +---- hw/bsp/espressif/family.cmake | 6 +-- src/common/tusb_mcu.h | 5 +- src/portable/analog/max3421/hcd_max3421.c | 2 +- src/tusb_option.h | 2 + 21 files changed, 94 insertions(+), 49 deletions(-) create mode 100644 hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake create mode 100644 hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.h diff --git a/examples/device/board_test/src/tusb_config.h b/examples/device/board_test/src/tusb_config.h index 1a27cc87f..36eafe807 100644 --- a/examples/device/board_test/src/tusb_config.h +++ b/examples/device/board_test/src/tusb_config.h @@ -49,7 +49,7 @@ #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define CFG_TUSB_OS_INC_PATH freertos/ #endif diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index e94e8eaec..607d40270 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -30,7 +30,7 @@ #include "bsp/board_api.h" #include "tusb.h" -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" @@ -111,14 +111,14 @@ int main(void) { #endif // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 -#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if !TUP_MCU_ESPRESSIF vTaskStartScheduler(); #endif return 0; } -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF void app_main(void) { main(); } diff --git a/examples/device/cdc_msc_freertos/src/tusb_config.h b/examples/device/cdc_msc_freertos/src/tusb_config.h index 91efe7d40..e743c9148 100644 --- a/examples/device/cdc_msc_freertos/src/tusb_config.h +++ b/examples/device/cdc_msc_freertos/src/tusb_config.h @@ -59,7 +59,7 @@ #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define CFG_TUSB_OS_INC_PATH freertos/ #endif diff --git a/examples/device/hid_composite_freertos/src/main.c b/examples/device/hid_composite_freertos/src/main.c index ff2cb635e..2bd545bc2 100644 --- a/examples/device/hid_composite_freertos/src/main.c +++ b/examples/device/hid_composite_freertos/src/main.c @@ -31,7 +31,7 @@ #include "tusb.h" #include "usb_descriptors.h" -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" @@ -113,14 +113,14 @@ int main(void) xTimerStart(blinky_tm, 0); // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 -#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if !TUP_MCU_ESPRESSIF vTaskStartScheduler(); #endif return 0; } -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF void app_main(void) { main(); diff --git a/examples/device/hid_composite_freertos/src/tusb_config.h b/examples/device/hid_composite_freertos/src/tusb_config.h index 3ba9bf311..0689e0f23 100644 --- a/examples/device/hid_composite_freertos/src/tusb_config.h +++ b/examples/device/hid_composite_freertos/src/tusb_config.h @@ -59,7 +59,7 @@ #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define CFG_TUSB_OS_INC_PATH freertos/ #endif diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index 2a2b0961f..ddb51e03a 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -288,7 +288,7 @@ void led_blinking_task(void* param) { #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE #define VIDEO_STACK_SIZE (configMINIMAL_STACK_SIZE*4) -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define USBD_STACK_SIZE 4096 int main(void); void app_main(void) { @@ -344,7 +344,7 @@ void freertos_init_task(void) { #endif // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 - #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + #if !TUP_MCU_ESPRESSIF vTaskStartScheduler(); #endif } diff --git a/examples/device/video_capture/src/tusb_config.h b/examples/device/video_capture/src/tusb_config.h index bdfc37d87..21483a2da 100644 --- a/examples/device/video_capture/src/tusb_config.h +++ b/examples/device/video_capture/src/tusb_config.h @@ -58,7 +58,7 @@ #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define CFG_TUSB_OS_INC_PATH freertos/ #endif diff --git a/examples/device/video_capture_2ch/src/main.c b/examples/device/video_capture_2ch/src/main.c index eb1cf2580..e8c2ec6b0 100644 --- a/examples/device/video_capture_2ch/src/main.c +++ b/examples/device/video_capture_2ch/src/main.c @@ -296,7 +296,7 @@ void led_blinking_task(void* param) { #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE #define VIDEO_STACK_SIZE (configMINIMAL_STACK_SIZE*4) -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define USBD_STACK_SIZE 4096 int main(void); void app_main(void) { @@ -352,7 +352,7 @@ void freertos_init_task(void) { #endif // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 - #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + #if !TUP_MCU_ESPRESSIF vTaskStartScheduler(); #endif } diff --git a/examples/device/video_capture_2ch/src/tusb_config.h b/examples/device/video_capture_2ch/src/tusb_config.h index fe66d63b5..43c7dfc90 100644 --- a/examples/device/video_capture_2ch/src/tusb_config.h +++ b/examples/device/video_capture_2ch/src/tusb_config.h @@ -58,7 +58,7 @@ #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define CFG_TUSB_OS_INC_PATH freertos/ #endif diff --git a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c index 7d246af67..f3495ab28 100644 --- a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c +++ b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c @@ -27,7 +27,7 @@ #include "tusb.h" #include "bsp/board_api.h" -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" diff --git a/examples/host/cdc_msc_hid_freertos/src/main.c b/examples/host/cdc_msc_hid_freertos/src/main.c index 069cbdc90..a6cb4d460 100644 --- a/examples/host/cdc_msc_hid_freertos/src/main.c +++ b/examples/host/cdc_msc_hid_freertos/src/main.c @@ -30,7 +30,7 @@ #include "bsp/board_api.h" #include "tusb.h" -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" @@ -107,14 +107,14 @@ int main(void) { xTimerStart(blinky_tm, 0); // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 -#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if !TUP_MCU_ESPRESSIF vTaskStartScheduler(); #endif return 0; } -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF void app_main(void) { main(); } diff --git a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h index 35de5ee50..0aab2cd2f 100644 --- a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h +++ b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h @@ -44,7 +44,7 @@ #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define CFG_TUSB_OS_INC_PATH freertos/ #endif diff --git a/hw/bsp/board_api.h b/hw/bsp/board_api.h index f21a32371..eee9ed9c5 100644 --- a/hw/bsp/board_api.h +++ b/hw/bsp/board_api.h @@ -39,7 +39,7 @@ extern "C" { #include "tusb.h" #if CFG_TUSB_OS == OPT_OS_FREERTOS -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" diff --git a/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake b/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake new file mode 100644 index 000000000..18c956714 --- /dev/null +++ b/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake @@ -0,0 +1,2 @@ +# Apply board specific content here +set(IDF_TARGET "esp32") diff --git a/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.h b/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.h new file mode 100644 index 000000000..0c53df06b --- /dev/null +++ b/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.h @@ -0,0 +1,53 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define NEOPIXEL_PIN 0 +#define NEOPIXEL_POWER_PIN 2 +#define NEOPIXEL_POWER_STATE 1 + +#define BUTTON_PIN 38 +#define BUTTON_STATE_ACTIVE 0 + +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI3_HOST +#define MAX3421_SCK_PIN 5 +#define MAX3421_MOSI_PIN 19 +#define MAX3421_MISO_PIN 21 +#define MAX3421_CS_PIN 33 +#define MAX3421_INTR_PIN 15 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/espressif/boards/family.c b/hw/bsp/espressif/boards/family.c index 5599d1504..02e478a0c 100644 --- a/hw/bsp/espressif/boards/family.c +++ b/hw/bsp/espressif/boards/family.c @@ -30,8 +30,12 @@ #include "esp_rom_gpio.h" #include "esp_mac.h" #include "hal/gpio_ll.h" + +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) #include "hal/usb_hal.h" #include "soc/usb_periph.h" +static void configure_pins(usb_hal_context_t* usb); +#endif #include "driver/gpio.h" #include "driver/uart.h" @@ -56,7 +60,6 @@ static led_strip_handle_t led_strip; static void max3421_init(void); #endif -static void configure_pins(usb_hal_context_t* usb); //--------------------------------------------------------------------+ // Implementation @@ -100,7 +103,6 @@ void board_init(void) { }; ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); - led_strip_clear(led_strip); // off #endif @@ -109,6 +111,7 @@ void board_init(void) { gpio_set_direction(BUTTON_PIN, GPIO_MODE_INPUT); gpio_set_pull_mode(BUTTON_PIN, BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN_ONLY : GPIO_PULLUP_ONLY); +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) // USB Controller Hal init periph_module_reset(PERIPH_USB_MODULE); periph_module_enable(PERIPH_USB_MODULE); @@ -118,12 +121,14 @@ void board_init(void) { }; usb_hal_init(&hal); configure_pins(&hal); +#endif #if CFG_TUH_ENABLED && CFG_TUH_MAX3421 max3421_init(); #endif } +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) static void configure_pins(usb_hal_context_t* usb) { /* usb_periph_iopins currently configures USB_OTG as USB Device. * Introduce additional parameters in usb_hal_context_t when adding support @@ -153,6 +158,7 @@ static void configure_pins(usb_hal_context_t* usb) { gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3); } } +#endif //--------------------------------------------------------------------+ // Board porting API @@ -208,15 +214,12 @@ SemaphoreHandle_t max3421_intr_sem; static void IRAM_ATTR max3421_isr_handler(void* arg) { (void) arg; // arg is gpio num - gpio_set_level(13, 1); BaseType_t xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR(max3421_intr_sem, &xHigherPriorityTaskWoken); if (xHigherPriorityTaskWoken) { portYIELD_FROM_ISR(); } - - gpio_set_level(13, 0); } static void max3421_intr_task(void* param) { @@ -250,16 +253,12 @@ static void max3421_init(void) { spi_device_interface_config_t max3421_cfg = { .mode = 0, - .clock_speed_hz = 26000000, + .clock_speed_hz = 20000000, // S2/S3 can work with 26 Mhz, but esp32 seems only work up to 20 Mhz .spics_io_num = -1, // manual control CS .queue_size = 1 }; ESP_ERROR_CHECK(spi_bus_add_device(MAX3421_SPI_HOST, &max3421_cfg, &max3421_spi)); - // debug - gpio_set_direction(13, GPIO_MODE_OUTPUT); - gpio_set_level(13, 0); - // Interrupt pin max3421_intr_sem = xSemaphoreCreateBinary(); xTaskCreate(max3421_intr_task, "max3421 intr", 2048, NULL, configMAX_PRIORITIES - 2, NULL); diff --git a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt index abe276910..8bdb3802e 100644 --- a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt +++ b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt @@ -5,17 +5,7 @@ set(includes_public) set(compile_options) set(tusb_src "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src") -if(target STREQUAL "esp32s3") - set(tusb_mcu "OPT_MCU_ESP32S3") -elseif(target STREQUAL "esp32s2") - set(tusb_mcu "OPT_MCU_ESP32S2") -else() - # CONFIG_TINYUSB dependency has been guaranteed by Kconfig logic, - # So it's not possible that cmake goes here - message(FATAL_ERROR "TinyUSB is not support on ${target}.") - return() -endif() - +string(TOUPPER OPT_MCU_${target} tusb_mcu) list(APPEND compile_definitions CFG_TUSB_MCU=${tusb_mcu} CFG_TUSB_OS=OPT_OS_FREERTOS diff --git a/hw/bsp/espressif/family.cmake b/hw/bsp/espressif/family.cmake index 92a9bcb04..eb97401c3 100644 --- a/hw/bsp/espressif/family.cmake +++ b/hw/bsp/espressif/family.cmake @@ -3,11 +3,7 @@ cmake_minimum_required(VERSION 3.5) # Apply board specific content i.e IDF_TARGET must be set before project.cmake is included include("${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake") -if(IDF_TARGET STREQUAL "esp32s2") - set(FAMILY_MCUS ESP32S2) -elseif(IDF_TARGET STREQUAL "esp32s3") - set(FAMILY_MCUS ESP32S3) -endif() +string(TOUPPER ${IDF_TARGET} FAMILY_MCUS) # Add example src and bsp directories set(EXTRA_COMPONENT_DIRS "src" "${CMAKE_CURRENT_LIST_DIR}/boards" "${CMAKE_CURRENT_LIST_DIR}/components") diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 0ae2573cd..2c4d7461d 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -329,6 +329,9 @@ #define TUP_USBIP_DWC2 #define TUP_DCD_ENDPOINT_MAX 6 +#elif TU_CHECK_MCU(OPT_MCU_ESP32) && (CFG_TUD_ENABLED || !(defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)) + #error "MCUs are only supported with CFG_TUH_MAX3421 enabled" + //--------------------------------------------------------------------+ // Dialog //--------------------------------------------------------------------+ @@ -426,7 +429,7 @@ #define TUP_MCU_MULTIPLE_CORE 0 #endif -#ifndef TUP_DCD_ENDPOINT_MAX +#if CFG_TUD_ENABLED && !defined(TUP_DCD_ENDPOINT_MAX) #warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" #define TUP_DCD_ENDPOINT_MAX 8 #endif diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 39afb7505..053169bf2 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -484,8 +484,8 @@ bool hcd_init(uint8_t rhport) { // v1 is 0x01, v2 is 0x12, v3 is 0x13 uint8_t const revision = reg_read(rhport, REVISION_ADDR, false); - TU_ASSERT(revision == 0x01 || revision == 0x12 || revision == 0x13, false); TU_LOG2_HEX(revision); + TU_ASSERT(revision == 0x01 || revision == 0x12 || revision == 0x13, false); // reset reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false); diff --git a/src/tusb_option.h b/src/tusb_option.h index cbcb69edd..25412d432 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -119,6 +119,8 @@ // Espressif #define OPT_MCU_ESP32S2 900 ///< Espressif ESP32-S2 #define OPT_MCU_ESP32S3 901 ///< Espressif ESP32-S3 +#define OPT_MCU_ESP32 902 ///< Espressif ESP32 (for host max3421e) +#define TUP_MCU_ESPRESSIF (CFG_TUSB_MCU >= 900 && CFG_TUSB_MCU < 1000) // check if Espressif MCU // Dialog #define OPT_MCU_DA1469X 1000 ///< Dialog Semiconductor DA1469x -- cgit v1.3.1 From 03ccc8d8dfe21fc158fc5eb8a4f3f90f425f8a3b Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Apr 2024 20:41:44 +0700 Subject: revert a change in tusb_mcu --- src/common/tusb_mcu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 2c4d7461d..00526bdba 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -429,7 +429,7 @@ #define TUP_MCU_MULTIPLE_CORE 0 #endif -#if CFG_TUD_ENABLED && !defined(TUP_DCD_ENDPOINT_MAX) +#if !defined(TUP_DCD_ENDPOINT_MAX) #warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" #define TUP_DCD_ENDPOINT_MAX 8 #endif -- cgit v1.3.1 From 223ce56625474764dc00229c44731858abcf4f29 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 26 Apr 2024 00:10:57 +0700 Subject: - add esp32 c3, c6 mcu option - skip breakpoint for espressif riscv --- examples/host/cdc_msc_hid_freertos/src/main.c | 5 ++++- src/common/tusb_mcu.h | 4 ++-- src/common/tusb_verify.h | 2 +- src/portable/analog/max3421/hcd_max3421.c | 2 ++ src/tusb_option.h | 2 ++ 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/examples/host/cdc_msc_hid_freertos/src/main.c b/examples/host/cdc_msc_hid_freertos/src/main.c index a6cb4d460..fa799aede 100644 --- a/examples/host/cdc_msc_hid_freertos/src/main.c +++ b/examples/host/cdc_msc_hid_freertos/src/main.c @@ -126,7 +126,10 @@ static void usb_host_task(void *param) { (void) param; // init host stack on configured roothub port - tuh_init(BOARD_TUH_RHPORT); + if (!tuh_init(BOARD_TUH_RHPORT)) { + printf("Failed to init USB Host Stack\r\n"); + vTaskSuspend(NULL); + } if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 00526bdba..5a567f2d5 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -429,8 +429,8 @@ #define TUP_MCU_MULTIPLE_CORE 0 #endif -#if !defined(TUP_DCD_ENDPOINT_MAX) - #warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" +#if !defined(TUP_DCD_ENDPOINT_MAX) && defined(CFG_TUD_ENABLED) && CFG_TUD_ENABLED +#warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" #define TUP_DCD_ENDPOINT_MAX 8 #endif diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index 71406dacf..0a9549c99 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -84,7 +84,7 @@ if ( (*ARM_CM_DHCSR) & 1UL ) __asm("BKPT #0\n"); /* Only halt mcu if debugger is attached */ \ } while(0) -#elif defined(__riscv) +#elif defined(__riscv) && !TUP_MCU_ESPRESSIF #define TU_BREAKPOINT() do { __asm("ebreak\n"); } while(0) #elif defined(_mips) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 053169bf2..4dc93d2d8 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -479,6 +479,8 @@ bool hcd_init(uint8_t rhport) { _hcd_data.spi_mutex = osal_mutex_create(&_hcd_data.spi_mutexdef); #endif + // NOTE: driver does not seem to work without nRST pin signal + // full duplex, interrupt negative edge reg_write(rhport, PINCTL_ADDR, _tuh_cfg.pinctl | PINCTL_FDUPSPI, false); diff --git a/src/tusb_option.h b/src/tusb_option.h index 25412d432..3ead20ee7 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -120,6 +120,8 @@ #define OPT_MCU_ESP32S2 900 ///< Espressif ESP32-S2 #define OPT_MCU_ESP32S3 901 ///< Espressif ESP32-S3 #define OPT_MCU_ESP32 902 ///< Espressif ESP32 (for host max3421e) +#define OPT_MCU_ESP32C3 903 ///< Espressif ESP32-C3 +#define OPT_MCU_ESP32C6 904 ///< Espressif ESP32-C6 #define TUP_MCU_ESPRESSIF (CFG_TUSB_MCU >= 900 && CFG_TUSB_MCU < 1000) // check if Espressif MCU // Dialog -- cgit v1.3.1 From 022de87550fdc63dd6dea91f39feecfce59eabe5 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 26 Apr 2024 00:15:04 +0700 Subject: add devkit c3 board --- .../boards/espressif_c3_devkitc/board.cmake | 2 + .../espressif/boards/espressif_c3_devkitc/board.h | 51 ++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 hw/bsp/espressif/boards/espressif_c3_devkitc/board.cmake create mode 100644 hw/bsp/espressif/boards/espressif_c3_devkitc/board.h diff --git a/hw/bsp/espressif/boards/espressif_c3_devkitc/board.cmake b/hw/bsp/espressif/boards/espressif_c3_devkitc/board.cmake new file mode 100644 index 000000000..ab4bc1a06 --- /dev/null +++ b/hw/bsp/espressif/boards/espressif_c3_devkitc/board.cmake @@ -0,0 +1,2 @@ +# Apply board specific content here +set(IDF_TARGET "esp32c3") diff --git a/hw/bsp/espressif/boards/espressif_c3_devkitc/board.h b/hw/bsp/espressif/boards/espressif_c3_devkitc/board.h new file mode 100644 index 000000000..243dd47f6 --- /dev/null +++ b/hw/bsp/espressif/boards/espressif_c3_devkitc/board.h @@ -0,0 +1,51 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define NEOPIXEL_PIN 8 + +#define BUTTON_PIN 9 +#define BUTTON_STATE_ACTIVE 0 + +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI2_HOST +#define MAX3421_SCK_PIN 4 +#define MAX3421_MOSI_PIN 6 +#define MAX3421_MISO_PIN 5 +#define MAX3421_CS_PIN 10 +#define MAX3421_INTR_PIN 7 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ -- cgit v1.3.1 From cde722385c579fc388fcf78ddb57fad22a643ba5 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 5 Apr 2024 22:19:45 +0200 Subject: dwc2: add dma support. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 154 +++++++++++++++++++++++++++------- 1 file changed, 124 insertions(+), 30 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 692096fc8..2e679d1f3 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -67,6 +67,11 @@ // Debug level for DWC2 #define DWC2_DEBUG 2 +// DMA switch +#ifndef DWC2_ENABLE_DMA +#define DWC2_ENABLE_DMA 1 +#endif + #ifndef dcache_clean #define dcache_clean(_addr, _size) #endif @@ -186,6 +191,32 @@ static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { return true; } +static bool dma_supported(uint8_t rhport) +{ + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + // Internal DMA only + return (dwc2->ghwcfg2_bm.arch == 2) && DWC2_ENABLE_DMA; +} + +static void dma_stpkt_rx(uint8_t rhport) +{ + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + + if (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a) { + if(dwc2->epout[0].doepctl & DOEPCTL_EPENA) + return; + } + + // Receive only 1 packet + dwc2->epout[0].doeptsiz = 0; + dwc2->epout[0].doeptsiz |= (1 << DOEPTSIZ_STUPCNT_Pos); + dwc2->epout[0].doeptsiz |= 8; + dwc2->epout[0].doeptsiz |= (1 << DOEPTSIZ_PKTCNT_Pos); + dwc2->epout[0].doepdma = (uintptr_t)_setup_packet; + + dwc2->epout[0].doepctl |= DOEPCTL_EPENA | DOEPCTL_USBAEP; +} + static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); @@ -351,6 +382,11 @@ static void bus_reset(uint8_t rhport) { // Setup the control endpoint 0 _allocated_fifo_words_tx = 16; + // DMA needs extra space for processing, needs size confirmation + if(dma_supported(rhport)) { + _allocated_fifo_words_tx += 72; + } + // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) dwc2->dieptxf0 = (16 << DIEPTXF0_TX0FD_Pos) | (_dwc2_controller[rhport].ep_fifo_size / 4 - _allocated_fifo_words_tx); @@ -361,6 +397,10 @@ static void bus_reset(uint8_t rhport) { dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); + if(dma_supported(rhport)) { + dma_stpkt_rx(rhport); + } + dwc2->gintmsk |= GINTMSK_OEPINT | GINTMSK_IEPINT; } @@ -369,11 +409,11 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); + xfer_ctl_t* const xfer = XFER_CTL_BASE(epnum, dir); // EP0 is limited to one packet each xfer // We use multiple transaction of xfer->max_size length to get a whole transfer done if (epnum == 0) { - xfer_ctl_t* const xfer = XFER_CTL_BASE(epnum, dir); total_bytes = tu_min16(ep0_pending[dir], xfer->max_size); ep0_pending[dir] -= total_bytes; } @@ -386,17 +426,31 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c epin[epnum].dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) | ((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk); - epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; + if(dma_supported(rhport)) { + epin[epnum].diepdma = (uintptr_t)xfer->buffer; - // For ISO endpoint set correct odd/even bit for next frame. - if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { - // Take odd/even bit from frame counter. - uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); - epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); - } - // Enable fifo empty interrupt only if there are something to put in the fifo. - if (total_bytes != 0) { - dwc2->diepempmsk |= (1 << epnum); + // For ISO endpoint set correct odd/even bit for next frame. + if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { + // Take odd/even bit from frame counter. + uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); + epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); + } + + epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; + } else { + + epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; + + // For ISO endpoint set correct odd/even bit for next frame. + if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { + // Take odd/even bit from frame counter. + uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); + epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); + } + // Enable fifo empty interrupt only if there are something to put in the fifo. + if (total_bytes != 0) { + dwc2->diepempmsk |= (1 << epnum); + } } } else { dwc2_epout_t* epout = dwc2->epout; @@ -406,13 +460,18 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c epout[epnum].doeptsiz |= (num_packets << DOEPTSIZ_PKTCNT_Pos) | ((total_bytes << DOEPTSIZ_XFRSIZ_Pos) & DOEPTSIZ_XFRSIZ_Msk); - epout[epnum].doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK; if ((epout[epnum].doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 && XFER_CTL_BASE(epnum, dir)->interval == 1) { // Take odd/even bit from frame counter. uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); epout[epnum].doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk); } + + if(dma_supported(rhport)) { + epout[epnum].doepdma = (uintptr_t)xfer->buffer; + } + + epout[epnum].doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK; } } @@ -619,6 +678,11 @@ void dcd_init(uint8_t rhport) { // Enable global interrupt dwc2->gahbcfg |= GAHBCFG_GINT; + if (dma_supported(rhport)) { + dwc2->gahbcfg |= GAHBCFG_DMAEN | GAHBCFG_HBSTLEN_2; + dwc2->gintmsk &=~GINTMSK_RXFLVLM; + } + // make sure we are in device mode // TU_ASSERT(!(dwc2->gintsts & GINTSTS_CMOD), ); @@ -728,6 +792,11 @@ void dcd_edpt_close_all(uint8_t rhport) { // reset allocated fifo IN _allocated_fifo_words_tx = 16; + // DMA needs extra space for processing, needs size confirmation + if(dma_supported(rhport)) { + _allocated_fifo_words_tx += 72; + } + fifo_flush_tx(dwc2, 0x10); // all tx fifo fifo_flush_rx(dwc2); } @@ -809,6 +878,9 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { edpt_disable(rhport, ep_addr, true); + if((tu_edpt_number(ep_addr) == 0) && dma_supported(rhport)) { + dma_stpkt_rx(rhport); + } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { @@ -991,32 +1063,51 @@ static void handle_epout_irq(uint8_t rhport) { uint32_t const doepint = epout->doepint; - // SETUP packet Setup Phase done. - if (doepint & DOEPINT_STUP) { - uint32_t clear_flag = DOEPINT_STUP; - - // STPKTRX is only available for version from 3_00a - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { - clear_flag |= DOEPINT_STPKTRX; - } - - epout->doepint = clear_flag; - dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true); - } - // OUT XFER complete if (epout->doepint & DOEPINT_XFRC) { epout->doepint = DOEPINT_XFRC; xfer_ctl_t* xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); - // EP0 can only handle one packet - if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { - // Schedule another packet to be received. - edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + if (doepint & DOEPINT_STUP) { + // STPKTRX is only available for version from 3_00a + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_STPKTRX; + } + } else if (doepint & DOEPINT_OTEPSPR) { + epout->doepint = DOEPINT_OTEPSPR; } else { - dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + // EP0 can only handle one packet + if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + // Schedule another packet to be received. + edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + } else { + if(dma_supported(rhport)) { + // Fix packet length + uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; + xfer->total_len -= remain; + // this is ZLP, so prepare EP0 for next setup + if(n == 0 && xfer->total_len == 0) { + dma_stpkt_rx(rhport); + } + } + + dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + } + } + } + + // SETUP packet Setup Phase done. + if (doepint & DOEPINT_STUP) { + epout->doepint = DOEPINT_STUP; + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_STPKTRX; + } + if(dma_supported(rhport) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { + dma_stpkt_rx(rhport); } + + dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true); } } } @@ -1042,6 +1133,9 @@ static void handle_epin_irq(uint8_t rhport) { // Schedule another packet to be transmitted. edpt_schedule_packets(rhport, n, TUSB_DIR_IN, 1, ep0_pending[TUSB_DIR_IN]); } else { + if((n == 0) && dma_supported(rhport)) { + dma_stpkt_rx(rhport); + } dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); } } -- cgit v1.3.1 From 394dc0686a5c26bd3375ce9aba12b82fa18ba42f Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 25 Apr 2024 22:09:59 +0200 Subject: Check IN ep count limit. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 13 +++++++++++++ src/portable/synopsys/dwc2/dwc2_esp32.h | 5 +++-- src/portable/synopsys/dwc2/dwc2_type.h | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 2e679d1f3..cdf6c2a68 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -103,6 +103,9 @@ static uint16_t ep0_pending[2]; // Index determines direction as t // TX FIFO RAM allocation so far in words - RX FIFO size is readily available from dwc2->grxfsiz static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs) +// Number of IN endpoints active +static uint8_t _allocated_ep_in_count; + // SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by static bool _sof_en; @@ -170,6 +173,12 @@ static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { dwc2->grxfsiz = sz; } } else { + // Check IN endpoints concurrently active limit + if(_dwc2_controller->ep_in_count) { + TU_ASSERT(_allocated_ep_in_count < _dwc2_controller->ep_in_count); + _allocated_ep_in_count++; + } + // Note if The TXFELVL is configured as half empty. In order // to be able to write a packet at that point, the fifo must be twice the max_size. if ((dwc2->gahbcfg & GAHBCFG_TXFELVL) == 0) { @@ -303,6 +312,8 @@ static void bus_reset(uint8_t rhport) { _sof_en = false; + _allocated_ep_in_count = 1; + // clear device address dwc2->dcfg &= ~DCFG_DAD_Msk; @@ -770,6 +781,8 @@ void dcd_edpt_close_all(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const ep_count = _dwc2_controller[rhport].ep_count; + _allocated_ep_in_count = 1; + // Disable non-control interrupt dwc2->daintmsk = (1 << DAINTMSK_OEPM_Pos) | (1 << DAINTMSK_IEPM_Pos); diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index c50dd66b8..fc12d7551 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -37,11 +37,12 @@ //#include "soc/usb_periph.h" #define DWC2_REG_BASE 0x60080000UL -#define DWC2_EP_MAX 6 // USB_OUT_EP_NUM. TODO ESP32Sx only has 5 tx fifo (5 endpoint IN) +#define DWC2_EP_MAX 7 +#define DWC2_EP_IN_MAX 5 static const dwc2_controller_t _dwc2_controller[] = { - { .reg_base = DWC2_REG_BASE, .irqnum = 0, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 1024 } + { .reg_base = DWC2_REG_BASE, .irqnum = 0, .ep_count = DWC2_EP_MAX, .ep_in_count = DWC2_EP_IN_MAX, .ep_fifo_size = 1024 } }; static intr_handle_t usb_ih; diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index c15771237..5db453561 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -29,6 +29,7 @@ typedef struct uintptr_t reg_base; uint32_t irqnum; uint8_t ep_count; + uint8_t ep_in_count; uint32_t ep_fifo_size; }dwc2_controller_t; -- cgit v1.3.1 From 298f7f2d818d117785af9f79da79fbdb85120cd2 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 25 Apr 2024 22:11:49 +0200 Subject: Fix DMA FIFO reservation. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 16 +++++++++------- src/portable/synopsys/dwc2/dwc2_bcm.h | 2 +- src/portable/synopsys/dwc2/dwc2_type.h | 6 +++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index cdf6c2a68..1057ee925 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -393,9 +393,10 @@ static void bus_reset(uint8_t rhport) { // Setup the control endpoint 0 _allocated_fifo_words_tx = 16; - // DMA needs extra space for processing, needs size confirmation + // DMA needs extra space for processing if(dma_supported(rhport)) { - _allocated_fifo_words_tx += 72; + uint16_t reserved = _dwc2_controller[rhport].ep_fifo_size / 4- dwc2->ghwcfg3_bm.total_fifo_size; + _allocated_fifo_words_tx += reserved; } // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) @@ -805,13 +806,14 @@ void dcd_edpt_close_all(uint8_t rhport) { // reset allocated fifo IN _allocated_fifo_words_tx = 16; - // DMA needs extra space for processing, needs size confirmation - if(dma_supported(rhport)) { - _allocated_fifo_words_tx += 72; - } - fifo_flush_tx(dwc2, 0x10); // all tx fifo fifo_flush_rx(dwc2); + + // DMA needs extra space for processing + if(dma_supported(rhport)) { + uint16_t reserved = _dwc2_controller[rhport].ep_fifo_size / 4- dwc2->ghwcfg3_bm.total_fifo_size; + _allocated_fifo_words_tx += reserved; + } } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { diff --git a/src/portable/synopsys/dwc2/dwc2_bcm.h b/src/portable/synopsys/dwc2/dwc2_bcm.h index 732d96ae0..e5824606a 100644 --- a/src/portable/synopsys/dwc2/dwc2_bcm.h +++ b/src/portable/synopsys/dwc2/dwc2_bcm.h @@ -39,7 +39,7 @@ static const dwc2_controller_t _dwc2_controller[] = { - { .reg_base = USB_OTG_GLOBAL_BASE, .irqnum = USB_IRQn, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 4096 } + { .reg_base = USB_OTG_GLOBAL_BASE, .irqnum = USB_IRQn, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 16384 } }; #define dcache_clean(_addr, _size) data_clean(_addr, _size) diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index 5db453561..08c9b8b1b 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -214,15 +214,15 @@ union { volatile uint32_t ghwcfg1; // 044 User Hardware Configuration1: endpoint dir (2 bit per ep) union { volatile uint32_t ghwcfg2; // 048 User Hardware Configuration2 - dwc2_ghwcfg2_t ghwcfg2_bm; + volatile dwc2_ghwcfg2_t ghwcfg2_bm; }; union { volatile uint32_t ghwcfg3; // 04C User Hardware Configuration3 - dwc2_ghwcfg3_t ghwcfg3_bm; + volatile dwc2_ghwcfg3_t ghwcfg3_bm; }; union { volatile uint32_t ghwcfg4; // 050 User Hardware Configuration4 - dwc2_ghwcfg4_t ghwcfg4_bm; + volatile dwc2_ghwcfg4_t ghwcfg4_bm; }; volatile uint32_t glpmcfg; // 054 Core LPM Configuration volatile uint32_t gpwrdn; // 058 Power Down -- cgit v1.3.1 From 87655682822690de87ade34ceca7c21ca65dd000 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 25 Apr 2024 22:39:19 +0200 Subject: Change DMA condition. --- src/class/audio/audio_device.c | 4 ++- src/portable/synopsys/dwc2/dcd_dwc2.c | 47 ++++++++++++++--------------------- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 9ba38a20c..b7af0259a 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -65,8 +65,10 @@ //--------------------------------------------------------------------+ // Use ring buffer if it's available, some MCUs need extra RAM requirements +// For DWC2 enable ring buffer will disable DMA (if available) #ifndef TUD_AUDIO_PREFER_RING_BUFFER - #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX + #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX || \ + defined(TUP_USBIP_DWC2) #define TUD_AUDIO_PREFER_RING_BUFFER 0 #else #define TUD_AUDIO_PREFER_RING_BUFFER 1 diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 1057ee925..c4b1956ce 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -67,23 +67,6 @@ // Debug level for DWC2 #define DWC2_DEBUG 2 -// DMA switch -#ifndef DWC2_ENABLE_DMA -#define DWC2_ENABLE_DMA 1 -#endif - -#ifndef dcache_clean -#define dcache_clean(_addr, _size) -#endif - -#ifndef dcache_invalidate -#define dcache_invalidate(_addr, _size) -#endif - -#ifndef dcache_clean_invalidate -#define dcache_clean_invalidate(_addr, _size) -#endif - static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; typedef struct { @@ -200,11 +183,17 @@ static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { return true; } -static bool dma_supported(uint8_t rhport) +static inline bool dma_enabled(uint8_t rhport) { + // DMA doesn't support fifo transfer +#ifdef TUD_AUDIO_PREFER_RING_BUFFER +#if TUD_AUDIO_PREFER_RING_BUFFER + return false; +#endif +#endif dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Internal DMA only - return (dwc2->ghwcfg2_bm.arch == 2) && DWC2_ENABLE_DMA; + return (dwc2->ghwcfg2_bm.arch == 2); } static void dma_stpkt_rx(uint8_t rhport) @@ -394,7 +383,7 @@ static void bus_reset(uint8_t rhport) { _allocated_fifo_words_tx = 16; // DMA needs extra space for processing - if(dma_supported(rhport)) { + if(dma_enabled(rhport)) { uint16_t reserved = _dwc2_controller[rhport].ep_fifo_size / 4- dwc2->ghwcfg3_bm.total_fifo_size; _allocated_fifo_words_tx += reserved; } @@ -409,7 +398,7 @@ static void bus_reset(uint8_t rhport) { dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); - if(dma_supported(rhport)) { + if(dma_enabled(rhport)) { dma_stpkt_rx(rhport); } @@ -438,7 +427,7 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c epin[epnum].dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) | ((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk); - if(dma_supported(rhport)) { + if(dma_enabled(rhport)) { epin[epnum].diepdma = (uintptr_t)xfer->buffer; // For ISO endpoint set correct odd/even bit for next frame. @@ -479,7 +468,7 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c epout[epnum].doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk); } - if(dma_supported(rhport)) { + if(dma_enabled(rhport)) { epout[epnum].doepdma = (uintptr_t)xfer->buffer; } @@ -690,7 +679,7 @@ void dcd_init(uint8_t rhport) { // Enable global interrupt dwc2->gahbcfg |= GAHBCFG_GINT; - if (dma_supported(rhport)) { + if (dma_enabled(rhport)) { dwc2->gahbcfg |= GAHBCFG_DMAEN | GAHBCFG_HBSTLEN_2; dwc2->gintmsk &=~GINTMSK_RXFLVLM; } @@ -810,7 +799,7 @@ void dcd_edpt_close_all(uint8_t rhport) { fifo_flush_rx(dwc2); // DMA needs extra space for processing - if(dma_supported(rhport)) { + if(dma_enabled(rhport)) { uint16_t reserved = _dwc2_controller[rhport].ep_fifo_size / 4- dwc2->ghwcfg3_bm.total_fifo_size; _allocated_fifo_words_tx += reserved; } @@ -893,7 +882,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { edpt_disable(rhport, ep_addr, true); - if((tu_edpt_number(ep_addr) == 0) && dma_supported(rhport)) { + if((tu_edpt_number(ep_addr) == 0) && dma_enabled(rhport)) { dma_stpkt_rx(rhport); } } @@ -1097,7 +1086,7 @@ static void handle_epout_irq(uint8_t rhport) { // Schedule another packet to be received. edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); } else { - if(dma_supported(rhport)) { + if(dma_enabled(rhport)) { // Fix packet length uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; xfer->total_len -= remain; @@ -1118,7 +1107,7 @@ static void handle_epout_irq(uint8_t rhport) { if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { epout->doepint = DOEPINT_STPKTRX; } - if(dma_supported(rhport) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { + if(dma_enabled(rhport) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { dma_stpkt_rx(rhport); } @@ -1148,7 +1137,7 @@ static void handle_epin_irq(uint8_t rhport) { // Schedule another packet to be transmitted. edpt_schedule_packets(rhport, n, TUSB_DIR_IN, 1, ep0_pending[TUSB_DIR_IN]); } else { - if((n == 0) && dma_supported(rhport)) { + if((n == 0) && dma_enabled(rhport)) { dma_stpkt_rx(rhport); } dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); -- cgit v1.3.1 From 7fb8d3341ce2feb46b0bce0bef069d31cf080168 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 26 Apr 2024 13:40:13 +0200 Subject: use separate buffer for ctrl transfer. --- src/class/hid/hid_device.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index ba77d3c5f..a5c709d4c 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -52,7 +52,7 @@ typedef struct CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE]; - CFG_TUSB_MEM_ALIGN uint8_t set_report_buf[CFG_TUD_HID_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf[CFG_TUD_HID_EP_BUFSIZE]; // TODO save hid descriptor since host can specifically request this after enumeration // Note: HID descriptor may be not available from application after enumeration @@ -296,7 +296,7 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t uint8_t const report_type = tu_u16_high(request->wValue); uint8_t const report_id = tu_u16_low(request->wValue); - uint8_t* report_buf = p_hid->epin_buf; + uint8_t* report_buf = p_hid->ctrl_buf; uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); uint16_t xferlen = 0; @@ -313,22 +313,22 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, req_len); TU_ASSERT( xferlen > 0 ); - tud_control_xfer(rhport, request, p_hid->epin_buf, xferlen); + tud_control_xfer(rhport, request, p_hid->ctrl_buf, xferlen); } break; case HID_REQ_CONTROL_SET_REPORT: if ( stage == CONTROL_STAGE_SETUP ) { - TU_VERIFY(request->wLength <= sizeof(p_hid->set_report_buf)); - tud_control_xfer(rhport, request, p_hid->set_report_buf, request->wLength); + TU_VERIFY(request->wLength <= sizeof(p_hid->ctrl_buf)); + tud_control_xfer(rhport, request, p_hid->ctrl_buf, request->wLength); } else if ( stage == CONTROL_STAGE_ACK ) { uint8_t const report_type = tu_u16_high(request->wValue); uint8_t const report_id = tu_u16_low(request->wValue); - uint8_t const* report_buf = p_hid->set_report_buf; + uint8_t const* report_buf = p_hid->ctrl_buf; uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); // If host request a specific Report ID, extract report ID in buffer before invoking callback -- cgit v1.3.1 From 1661acf82f8e01392de0c18c3472d016679c707d Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 26 Apr 2024 13:42:20 +0200 Subject: Add missing alignment. --- src/class/hid/hid_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index a5c709d4c..c66a4597e 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -46,9 +46,9 @@ typedef struct uint8_t ep_out; // optional Out endpoint uint8_t itf_protocol; // Boot mouse or keyboard - uint8_t protocol_mode; // Boot (0) or Report protocol (1) - uint8_t idle_rate; // up to application to handle idle rate uint16_t report_desc_len; + CFG_TUSB_MEM_ALIGN uint8_t protocol_mode; // Boot (0) or Report protocol (1) + CFG_TUSB_MEM_ALIGN uint8_t idle_rate; // up to application to handle idle rate CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE]; -- cgit v1.3.1 From 6c3a60e5f2100e3d60bfd4b9b3e28fbab98af1b5 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 26 Apr 2024 14:54:16 +0200 Subject: Update IAR template. --- tools/iar_gen.py | 3 ++ tools/iar_template.ipcf | 96 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/tools/iar_gen.py b/tools/iar_gen.py index 264dd9a58..ebcfa1423 100644 --- a/tools/iar_gen.py +++ b/tools/iar_gen.py @@ -56,6 +56,7 @@ def Main(): def ListPath(path, blacklist=[]): # Get all .c files files = glob.glob(f'../{path}/**/*.c', recursive=True) + files.extend(glob.glob(f'../{path}/**/*.h', recursive=True)) # Filter files = [x for x in files if all(y not in x for y in blacklist)] # Get common dir list @@ -77,6 +78,8 @@ def List(): ListPath('lib/SEGGER_RTT') if __name__ == "__main__": + if os.path.dirname(os.getcwd()) != 'tools': + os.chdir('tools') if (len(sys.argv) > 1): if (sys.argv[1] == 'l'): List() diff --git a/tools/iar_template.ipcf b/tools/iar_template.ipcf index c3683c3d7..e72ec0ce2 100644 --- a/tools/iar_template.ipcf +++ b/tools/iar_template.ipcf @@ -10,57 +10,101 @@ $TUSB_DIR$/src/tusb.c + $TUSB_DIR$/src/tusb.h + $TUSB_DIR$/src/tusb_option.h $TUSB_DIR$/src/class/audio/audio_device.c + $TUSB_DIR$/src/class/audio/audio.h + $TUSB_DIR$/src/class/audio/audio_device.h $TUSB_DIR$/src/class/bth/bth_device.c + $TUSB_DIR$/src/class/bth/bth_device.h $TUSB_DIR$/src/class/cdc/cdc_device.c $TUSB_DIR$/src/class/cdc/cdc_host.c $TUSB_DIR$/src/class/cdc/cdc_rndis_host.c + $TUSB_DIR$/src/class/cdc/cdc.h + $TUSB_DIR$/src/class/cdc/cdc_device.h + $TUSB_DIR$/src/class/cdc/cdc_host.h + $TUSB_DIR$/src/class/cdc/cdc_rndis.h + $TUSB_DIR$/src/class/cdc/cdc_rndis_host.h $TUSB_DIR$/src/class/dfu/dfu_device.c $TUSB_DIR$/src/class/dfu/dfu_rt_device.c + $TUSB_DIR$/src/class/dfu/dfu.h + $TUSB_DIR$/src/class/dfu/dfu_device.h + $TUSB_DIR$/src/class/dfu/dfu_rt_device.h $TUSB_DIR$/src/class/hid/hid_device.c $TUSB_DIR$/src/class/hid/hid_host.c + $TUSB_DIR$/src/class/hid/hid.h + $TUSB_DIR$/src/class/hid/hid_device.h + $TUSB_DIR$/src/class/hid/hid_host.h $TUSB_DIR$/src/class/midi/midi_device.c + $TUSB_DIR$/src/class/midi/midi.h + $TUSB_DIR$/src/class/midi/midi_device.h $TUSB_DIR$/src/class/msc/msc_device.c $TUSB_DIR$/src/class/msc/msc_host.c + $TUSB_DIR$/src/class/msc/msc.h + $TUSB_DIR$/src/class/msc/msc_device.h + $TUSB_DIR$/src/class/msc/msc_host.h $TUSB_DIR$/src/class/net/ecm_rndis_device.c $TUSB_DIR$/src/class/net/ncm_device.c + $TUSB_DIR$/src/class/net/ncm.h + $TUSB_DIR$/src/class/net/net_device.h $TUSB_DIR$/src/class/usbtmc/usbtmc_device.c + $TUSB_DIR$/src/class/usbtmc/usbtmc.h + $TUSB_DIR$/src/class/usbtmc/usbtmc_device.h $TUSB_DIR$/src/class/vendor/vendor_device.c $TUSB_DIR$/src/class/vendor/vendor_host.c + $TUSB_DIR$/src/class/vendor/vendor_device.h + $TUSB_DIR$/src/class/vendor/vendor_host.h $TUSB_DIR$/src/class/video/video_device.c + $TUSB_DIR$/src/class/video/video.h + $TUSB_DIR$/src/class/video/video_device.h $TUSB_DIR$/src/common/tusb_fifo.c + $TUSB_DIR$/src/common/tusb_common.h + $TUSB_DIR$/src/common/tusb_compiler.h + $TUSB_DIR$/src/common/tusb_debug.h + $TUSB_DIR$/src/common/tusb_fifo.h + $TUSB_DIR$/src/common/tusb_mcu.h + $TUSB_DIR$/src/common/tusb_private.h + $TUSB_DIR$/src/common/tusb_types.h + $TUSB_DIR$/src/common/tusb_verify.h $TUSB_DIR$/src/device/usbd.c $TUSB_DIR$/src/device/usbd_control.c + $TUSB_DIR$/src/device/dcd.h + $TUSB_DIR$/src/device/usbd.h + $TUSB_DIR$/src/device/usbd_pvt.h $TUSB_DIR$/src/host/hub.c $TUSB_DIR$/src/host/usbh.c + $TUSB_DIR$/src/host/hcd.h + $TUSB_DIR$/src/host/hub.h + $TUSB_DIR$/src/host/usbh.h + $TUSB_DIR$/src/host/usbh_pvt.h $TUSB_DIR$/src/portable/analog/max3421/hcd_max3421.c @@ -70,26 +114,39 @@ $TUSB_DIR$/src/portable/chipidea/ci_fs/dcd_ci_fs.c + $TUSB_DIR$/src/portable/chipidea/ci_fs/ci_fs_kinetis.h + $TUSB_DIR$/src/portable/chipidea/ci_fs/ci_fs_mcx.h + $TUSB_DIR$/src/portable/chipidea/ci_fs/ci_fs_type.h $TUSB_DIR$/src/portable/chipidea/ci_hs/dcd_ci_hs.c $TUSB_DIR$/src/portable/chipidea/ci_hs/hcd_ci_hs.c + $TUSB_DIR$/src/portable/chipidea/ci_hs/ci_hs_imxrt.h + $TUSB_DIR$/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h + $TUSB_DIR$/src/portable/chipidea/ci_hs/ci_hs_mcx.h + $TUSB_DIR$/src/portable/chipidea/ci_hs/ci_hs_type.h $TUSB_DIR$/src/portable/dialog/da146xx/dcd_da146xx.c $TUSB_DIR$/src/portable/ehci/ehci.c + $TUSB_DIR$/src/portable/ehci/ehci.h + $TUSB_DIR$/src/portable/ehci/ehci_api.h $TUSB_DIR$/src/portable/mentor/musb/dcd_musb.c $TUSB_DIR$/src/portable/mentor/musb/hcd_musb.c + $TUSB_DIR$/src/portable/mentor/musb/musb_msp432e.h + $TUSB_DIR$/src/portable/mentor/musb/musb_tm4c.h + $TUSB_DIR$/src/portable/mentor/musb/musb_type.h $TUSB_DIR$/src/portable/microchip/pic/dcd_pic.c $TUSB_DIR$/src/portable/microchip/pic32mz/dcd_pic32mz.c + $TUSB_DIR$/src/portable/microchip/pic32mz/usbhs_registers.h $TUSB_DIR$/src/portable/microchip/samd/dcd_samd.c @@ -99,6 +156,7 @@ $TUSB_DIR$/src/portable/microchip/samx7x/dcd_samx7x.c + $TUSB_DIR$/src/portable/microchip/samx7x/common_usb_regs.h $TUSB_DIR$/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c @@ -122,12 +180,14 @@ $TUSB_DIR$/src/portable/nxp/lpc17_40/dcd_lpc17_40.c $TUSB_DIR$/src/portable/nxp/lpc17_40/hcd_lpc17_40.c + $TUSB_DIR$/src/portable/nxp/lpc17_40/dcd_lpc17_40.h $TUSB_DIR$/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c $TUSB_DIR$/src/portable/ohci/ohci.c + $TUSB_DIR$/src/portable/ohci/ohci.h $TUSB_DIR$/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c @@ -137,42 +197,78 @@ $TUSB_DIR$/src/portable/raspberrypi/rp2040/dcd_rp2040.c $TUSB_DIR$/src/portable/raspberrypi/rp2040/hcd_rp2040.c $TUSB_DIR$/src/portable/raspberrypi/rp2040/rp2040_usb.c + $TUSB_DIR$/src/portable/raspberrypi/rp2040/rp2040_usb.h $TUSB_DIR$/src/portable/renesas/rusb2/dcd_rusb2.c $TUSB_DIR$/src/portable/renesas/rusb2/hcd_rusb2.c $TUSB_DIR$/src/portable/renesas/rusb2/rusb2_common.c + $TUSB_DIR$/src/portable/renesas/rusb2/rusb2_ra.h + $TUSB_DIR$/src/portable/renesas/rusb2/rusb2_rx.h + $TUSB_DIR$/src/portable/renesas/rusb2/rusb2_type.h $TUSB_DIR$/src/portable/sony/cxd56/dcd_cxd56.c $TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c + $TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h $TUSB_DIR$/src/portable/st/typec/typec_stm32.c $TUSB_DIR$/src/portable/sunxi/dcd_sunxi_musb.c + $TUSB_DIR$/src/portable/sunxi/musb_def.h $TUSB_DIR$/src/portable/synopsys/dwc2/dcd_dwc2.c + $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_bcm.h + $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_efm32.h + $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_esp32.h + $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_gd32.h + $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_stm32.h + $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_type.h + $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_xmc.h $TUSB_DIR$/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c $TUSB_DIR$/src/portable/valentyusb/eptri/dcd_eptri.c + $TUSB_DIR$/src/portable/valentyusb/eptri/dcd_eptri.h $TUSB_DIR$/src/portable/wch/dcd_ch32_usbhs.c + $TUSB_DIR$/src/portable/wch/ch32_usbhs_reg.h $TUSB_DIR$/src/typec/usbc.c + $TUSB_DIR$/src/typec/pd_types.h + $TUSB_DIR$/src/typec/tcd.h + $TUSB_DIR$/src/typec/usbc.h + + + $TUSB_DIR$/src/class/cdc/serial/ch34x.h + $TUSB_DIR$/src/class/cdc/serial/cp210x.h + $TUSB_DIR$/src/class/cdc/serial/ftdi_sio.h + + + $TUSB_DIR$/src/osal/osal.h + $TUSB_DIR$/src/osal/osal_freertos.h + $TUSB_DIR$/src/osal/osal_mynewt.h + $TUSB_DIR$/src/osal/osal_none.h + $TUSB_DIR$/src/osal/osal_pico.h + $TUSB_DIR$/src/osal/osal_rtthread.h + $TUSB_DIR$/src/osal/osal_rtx4.h $TUSB_DIR$/lib/SEGGER_RTT/RTT/SEGGER_RTT.c $TUSB_DIR$/lib/SEGGER_RTT/RTT/SEGGER_RTT_printf.c + $TUSB_DIR$/lib/SEGGER_RTT/RTT/SEGGER_RTT.h + + + $TUSB_DIR$/lib/SEGGER_RTT/Config/SEGGER_RTT_Conf.h -- cgit v1.3.1 From 4af67dd0078009c1378612440afd5806e84a81c7 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 26 Apr 2024 17:45:14 +0200 Subject: Simplify transfer failure cb. --- .clang-format | 6 ++++++ src/class/hid/hid_device.c | 6 ++++-- src/class/hid/hid_device.h | 3 +-- 3 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..4369c29fe --- /dev/null +++ b/.clang-format @@ -0,0 +1,6 @@ +--- +BreakBeforeBraces: Linux +ColumnLimit: '200' +ReflowComments: 'true' + +... diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 564ad12f6..637bc7f61 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -381,6 +381,8 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + (void) result; + uint8_t instance = 0; hidd_interface_t * p_hid = _hidd_itf; @@ -396,9 +398,9 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if (XFER_RESULT_SUCCESS != result) { // Inform application about the issue - if (tud_hid_report_issue_cb) + if (tud_hid_report_fail_cb) { - tud_hid_report_issue_cb(instance, ep_addr, result, (uint16_t) xferred_bytes); + tud_hid_report_fail_cb(instance, ep_addr, (uint16_t) xferred_bytes); } // Allow a new transfer to be received if issue happened on an OUT endpoint diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index a934753eb..9206d67f8 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -119,7 +119,7 @@ TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); // Invoked when a transfer wasn't successful -TU_ATTR_WEAK void tud_hid_report_issue_cb(uint8_t instance, uint8_t ep_addr, xfer_result_t result, uint16_t len); +TU_ATTR_WEAK void tud_hid_report_fail_cb(uint8_t instance, uint8_t ep_addr, uint16_t len); //--------------------------------------------------------------------+ // Inline Functions @@ -413,7 +413,6 @@ uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool hidd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); -void test(void); #ifdef __cplusplus } -- cgit v1.3.1 From 24339dbcce5c5374e0abedf605471753484e4a56 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 26 Apr 2024 18:01:02 +0200 Subject: Code format. --- src/class/hid/hid_device.c | 355 +++++++++++++++++++-------------------------- 1 file changed, 153 insertions(+), 202 deletions(-) diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 45c10862b..ada01582e 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -39,12 +39,11 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -typedef struct -{ +typedef struct { uint8_t itf_num; uint8_t ep_in; - uint8_t ep_out; // optional Out endpoint - uint8_t itf_protocol; // Boot mouse or keyboard + uint8_t ep_out; // optional Out endpoint + uint8_t itf_protocol; // Boot mouse or keyboard uint16_t report_desc_len; CFG_TUSB_MEM_ALIGN uint8_t protocol_mode; // Boot (0) or Report protocol (1) @@ -56,7 +55,7 @@ typedef struct // TODO save hid descriptor since host can specifically request this after enumeration // Note: HID descriptor may be not available from application after enumeration - tusb_hid_descriptor_hid_t const * hid_descriptor; + tusb_hid_descriptor_hid_t const *hid_descriptor; } hidd_interface_t; CFG_TUD_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID]; @@ -64,12 +63,12 @@ CFG_TUD_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID]; /*------------- Helpers -------------*/ static inline uint8_t get_index_by_itfnum(uint8_t itf_num) { - for (uint8_t i=0; i < CFG_TUD_HID; i++ ) - { - if ( itf_num == _hidd_itf[i].itf_num ) return i; - } + for (uint8_t i = 0; i < CFG_TUD_HID; i++) { + if (itf_num == _hidd_itf[i].itf_num) + return i; + } - return 0xFF; + return 0xFF; } //--------------------------------------------------------------------+ @@ -82,37 +81,29 @@ bool tud_hid_n_ready(uint8_t instance) return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(rhport, ep_in); } -bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint16_t len) +bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const *report, uint16_t len) { uint8_t const rhport = 0; - hidd_interface_t * p_hid = &_hidd_itf[instance]; + hidd_interface_t *p_hid = &_hidd_itf[instance]; // claim endpoint - TU_VERIFY( usbd_edpt_claim(rhport, p_hid->ep_in) ); + TU_VERIFY(usbd_edpt_claim(rhport, p_hid->ep_in)); // prepare data - if (report_id) - { + if (report_id) { p_hid->epin_buf[0] = report_id; - TU_VERIFY(0 == tu_memcpy_s(p_hid->epin_buf+1, CFG_TUD_HID_EP_BUFSIZE-1, report, len)); + TU_VERIFY(0 == tu_memcpy_s(p_hid->epin_buf + 1, CFG_TUD_HID_EP_BUFSIZE - 1, report, len)); len++; - }else - { + } else { TU_VERIFY(0 == tu_memcpy_s(p_hid->epin_buf, CFG_TUD_HID_EP_BUFSIZE, report, len)); } return usbd_edpt_xfer(rhport, p_hid->ep_in, p_hid->epin_buf, len); } -uint8_t tud_hid_n_interface_protocol(uint8_t instance) -{ - return _hidd_itf[instance].itf_protocol; -} +uint8_t tud_hid_n_interface_protocol(uint8_t instance) { return _hidd_itf[instance].itf_protocol; } -uint8_t tud_hid_n_get_protocol(uint8_t instance) -{ - return _hidd_itf[instance].protocol_mode; -} +uint8_t tud_hid_n_get_protocol(uint8_t instance) { return _hidd_itf[instance].protocol_mode; } bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) { @@ -121,27 +112,23 @@ bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modi report.modifier = modifier; report.reserved = 0; - if ( keycode ) - { + if (keycode) { memcpy(report.keycode, keycode, sizeof(report.keycode)); - }else - { + } else { tu_memclr(report.keycode, 6); } return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } -bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, - uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) +bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) { - hid_mouse_report_t report = - { + hid_mouse_report_t report = { .buttons = buttons, - .x = x, - .y = y, - .wheel = vertical, - .pan = horizontal + .x = x, + .y = y, + .wheel = vertical, + .pan = horizontal }; return tud_hid_n_report(instance, report_id, &report, sizeof(report)); @@ -149,29 +136,27 @@ bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) { - hid_abs_mouse_report_t report = - { + hid_abs_mouse_report_t report = { .buttons = buttons, - .x = x, - .y = y, - .wheel = vertical, - .pan = horizontal + .x = x, + .y = y, + .wheel = vertical, + .pan = horizontal }; return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } -bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, - int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) { - hid_gamepad_report_t report = - { - .x = x, - .y = y, - .z = z, - .rz = rz, - .rx = rx, - .ry = ry, - .hat = hat, - .buttons = buttons, +bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) +{ + hid_gamepad_report_t report = { + .x = x, + .y = y, + .z = z, + .rz = rz, + .rx = rx, + .ry = ry, + .hat = hat, + .buttons = buttons, }; return tud_hid_n_report(instance, report_id, &report, sizeof(report)); @@ -180,67 +165,64 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, //--------------------------------------------------------------------+ // USBD-CLASS API //--------------------------------------------------------------------+ -void hidd_init(void) { +void hidd_init(void) +{ hidd_reset(0); } -bool hidd_deinit(void) { +bool hidd_deinit(void) +{ return true; } void hidd_reset(uint8_t rhport) { - (void) rhport; + (void)rhport; tu_memclr(_hidd_itf, sizeof(_hidd_itf)); } -uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t max_len) - { +uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16_t max_len) +{ TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0); // len = interface + hid + n*endpoints - uint16_t const drv_len = - (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + - desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); + uint16_t const drv_len = (uint16_t)(sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(max_len >= drv_len, 0); // Find available interface - hidd_interface_t * p_hid = NULL; + hidd_interface_t *p_hid = NULL; uint8_t hid_id; - for(hid_id=0; hid_idhid_descriptor = (tusb_hid_descriptor_hid_t const *) p_desc; + p_hid->hid_descriptor = (tusb_hid_descriptor_hid_t const *)p_desc; //------------- Endpoint Descriptor -------------// p_desc = tu_desc_next(p_desc); TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, desc_itf->bNumEndpoints, TUSB_XFER_INTERRUPT, &p_hid->ep_out, &p_hid->ep_in), 0); - if ( desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT ) p_hid->itf_protocol = desc_itf->bInterfaceProtocol; + if (desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT) + p_hid->itf_protocol = desc_itf->bInterfaceProtocol; p_hid->protocol_mode = HID_PROTOCOL_REPORT; // Per Specs: default is report mode - p_hid->itf_num = desc_itf->bInterfaceNumber; + p_hid->itf_num = desc_itf->bInterfaceNumber; // Use offsetof to avoid pointer to the odd/misaligned address - p_hid->report_desc_len = tu_unaligned_read16((uint8_t const*) p_hid->hid_descriptor + offsetof(tusb_hid_descriptor_hid_t, wReportLength)); + p_hid->report_desc_len = tu_unaligned_read16((uint8_t const *)p_hid->hid_descriptor + offsetof(tusb_hid_descriptor_hid_t, wReportLength)); // Prepare for output endpoint - if (p_hid->ep_out) - { - if ( !usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf)) ) - { + if (p_hid->ep_out) { + if (!usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))) { TU_LOG_FAILED(); TU_BREAKPOINT(); } @@ -252,144 +234,120 @@ uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint1 // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) -bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); - uint8_t const hid_itf = get_index_by_itfnum((uint8_t) request->wIndex); + uint8_t const hid_itf = get_index_by_itfnum((uint8_t)request->wIndex); TU_VERIFY(hid_itf < CFG_TUD_HID); - hidd_interface_t* p_hid = &_hidd_itf[hid_itf]; + hidd_interface_t *p_hid = &_hidd_itf[hid_itf]; - if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) - { + if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { //------------- STD Request -------------// - if ( stage == CONTROL_STAGE_SETUP ) - { - uint8_t const desc_type = tu_u16_high(request->wValue); - //uint8_t const desc_index = tu_u16_low (request->wValue); + if (stage == CONTROL_STAGE_SETUP) { + uint8_t const desc_type = tu_u16_high(request->wValue); + // uint8_t const desc_index = tu_u16_low (request->wValue); - if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_HID) - { + if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_HID) { TU_VERIFY(p_hid->hid_descriptor); - TU_VERIFY(tud_control_xfer(rhport, request, (void*)(uintptr_t) p_hid->hid_descriptor, p_hid->hid_descriptor->bLength)); - } - else if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) - { - uint8_t const * desc_report = tud_hid_descriptor_report_cb(hid_itf); - tud_control_xfer(rhport, request, (void*)(uintptr_t) desc_report, p_hid->report_desc_len); - } - else - { + TU_VERIFY(tud_control_xfer(rhport, request, (void *)(uintptr_t)p_hid->hid_descriptor, p_hid->hid_descriptor->bLength)); + } else if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) { + uint8_t const *desc_report = tud_hid_descriptor_report_cb(hid_itf); + tud_control_xfer(rhport, request, (void *)(uintptr_t)desc_report, p_hid->report_desc_len); + } else { return false; // stall unsupported request } } - } - else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) - { + } else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) { //------------- Class Specific Request -------------// - switch( request->bRequest ) - { - case HID_REQ_CONTROL_GET_REPORT: - if ( stage == CONTROL_STAGE_SETUP ) - { - uint8_t const report_type = tu_u16_high(request->wValue); - uint8_t const report_id = tu_u16_low(request->wValue); + switch (request->bRequest) { + case HID_REQ_CONTROL_GET_REPORT: + if (stage == CONTROL_STAGE_SETUP) { + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); - uint8_t* report_buf = p_hid->ctrl_buf; - uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); + uint8_t *report_buf = p_hid->ctrl_buf; + uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); - uint16_t xferlen = 0; + uint16_t xferlen = 0; - // If host request a specific Report ID, add ID to as 1 byte of response - if ( (report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1) ) - { - *report_buf++ = report_id; - req_len--; + // If host request a specific Report ID, add ID to as 1 byte of response + if ((report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1)) { + *report_buf++ = report_id; + req_len--; - xferlen++; - } + xferlen++; + } - xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, req_len); - TU_ASSERT( xferlen > 0 ); + xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t)report_type, report_buf, req_len); + TU_ASSERT(xferlen > 0); - tud_control_xfer(rhport, request, p_hid->ctrl_buf, xferlen); - } + tud_control_xfer(rhport, request, p_hid->ctrl_buf, xferlen); + } break; - case HID_REQ_CONTROL_SET_REPORT: - if ( stage == CONTROL_STAGE_SETUP ) - { - TU_VERIFY(request->wLength <= sizeof(p_hid->ctrl_buf)); - tud_control_xfer(rhport, request, p_hid->ctrl_buf, request->wLength); - } - else if ( stage == CONTROL_STAGE_ACK ) - { - uint8_t const report_type = tu_u16_high(request->wValue); - uint8_t const report_id = tu_u16_low(request->wValue); - - uint8_t const* report_buf = p_hid->ctrl_buf; - uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); - - // If host request a specific Report ID, extract report ID in buffer before invoking callback - if ( (report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0]) ) - { - report_buf++; - report_len--; - } - - tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, report_len); + case HID_REQ_CONTROL_SET_REPORT: + if (stage == CONTROL_STAGE_SETUP) { + TU_VERIFY(request->wLength <= sizeof(p_hid->ctrl_buf)); + tud_control_xfer(rhport, request, p_hid->ctrl_buf, request->wLength); + } else if (stage == CONTROL_STAGE_ACK) { + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); + + uint8_t const *report_buf = p_hid->ctrl_buf; + uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); + + // If host request a specific Report ID, extract report ID in buffer before invoking callback + if ((report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0])) { + report_buf++; + report_len--; } + + tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t)report_type, report_buf, report_len); + } break; - case HID_REQ_CONTROL_SET_IDLE: - if ( stage == CONTROL_STAGE_SETUP ) - { - p_hid->idle_rate = tu_u16_high(request->wValue); - if ( tud_hid_set_idle_cb ) - { - // stall request if callback return false - TU_VERIFY( tud_hid_set_idle_cb( hid_itf, p_hid->idle_rate) ); - } - - tud_control_status(rhport, request); + case HID_REQ_CONTROL_SET_IDLE: + if (stage == CONTROL_STAGE_SETUP) { + p_hid->idle_rate = tu_u16_high(request->wValue); + if (tud_hid_set_idle_cb) { + // stall request if callback return false + TU_VERIFY(tud_hid_set_idle_cb(hid_itf, p_hid->idle_rate)); } + + tud_control_status(rhport, request); + } break; - case HID_REQ_CONTROL_GET_IDLE: - if ( stage == CONTROL_STAGE_SETUP ) - { - // TODO idle rate of report - tud_control_xfer(rhport, request, &p_hid->idle_rate, 1); - } + case HID_REQ_CONTROL_GET_IDLE: + if (stage == CONTROL_STAGE_SETUP) { + // TODO idle rate of report + tud_control_xfer(rhport, request, &p_hid->idle_rate, 1); + } break; - case HID_REQ_CONTROL_GET_PROTOCOL: - if ( stage == CONTROL_STAGE_SETUP ) - { - tud_control_xfer(rhport, request, &p_hid->protocol_mode, 1); - } + case HID_REQ_CONTROL_GET_PROTOCOL: + if (stage == CONTROL_STAGE_SETUP) { + tud_control_xfer(rhport, request, &p_hid->protocol_mode, 1); + } break; - case HID_REQ_CONTROL_SET_PROTOCOL: - if ( stage == CONTROL_STAGE_SETUP ) - { - tud_control_status(rhport, request); - } - else if ( stage == CONTROL_STAGE_ACK ) - { - p_hid->protocol_mode = (uint8_t) request->wValue; - if (tud_hid_set_protocol_cb) - { - tud_hid_set_protocol_cb(hid_itf, p_hid->protocol_mode); - } + case HID_REQ_CONTROL_SET_PROTOCOL: + if (stage == CONTROL_STAGE_SETUP) { + tud_control_status(rhport, request); + } else if (stage == CONTROL_STAGE_ACK) { + p_hid->protocol_mode = (uint8_t)request->wValue; + if (tud_hid_set_protocol_cb) { + tud_hid_set_protocol_cb(hid_itf, p_hid->protocol_mode); } + } break; - default: return false; // stall unsupported request + default: + return false; // stall unsupported request } - }else - { + } else { return false; // stall unsupported request } @@ -398,31 +356,27 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - (void) result; + (void)result; uint8_t instance = 0; - hidd_interface_t * p_hid = _hidd_itf; + hidd_interface_t *p_hid = _hidd_itf; // Identify which interface to use - for (instance = 0; instance < CFG_TUD_HID; instance++) - { + for (instance = 0; instance < CFG_TUD_HID; instance++) { p_hid = &_hidd_itf[instance]; - if ( (ep_addr == p_hid->ep_out) || (ep_addr == p_hid->ep_in) ) break; + if ((ep_addr == p_hid->ep_out) || (ep_addr == p_hid->ep_in)) + break; } TU_ASSERT(instance < CFG_TUD_HID); // Check if there was a problem - if (XFER_RESULT_SUCCESS != result) - { - // Inform application about the issue - if (tud_hid_report_fail_cb) - { - tud_hid_report_fail_cb(instance, ep_addr, (uint16_t) xferred_bytes); + if (XFER_RESULT_SUCCESS != result) { // Inform application about the issue + if (tud_hid_report_fail_cb) { + tud_hid_report_fail_cb(instance, ep_addr, (uint16_t)xferred_bytes); } // Allow a new transfer to be received if issue happened on an OUT endpoint - if (ep_addr == p_hid->ep_out) - { + if (ep_addr == p_hid->ep_out) { // Prepare the OUT endpoint to be able to receive a new transfer TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); } @@ -431,17 +385,14 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ } // Sent report successfully - if (ep_addr == p_hid->ep_in) - { - if (tud_hid_report_complete_cb) - { - tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t) xferred_bytes); + if (ep_addr == p_hid->ep_in) { + if (tud_hid_report_complete_cb) { + tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t)xferred_bytes); } } // Received report successfully - else if (ep_addr == p_hid->ep_out) - { - tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t) xferred_bytes); + else if (ep_addr == p_hid->ep_out) { + tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t)xferred_bytes); TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); } -- cgit v1.3.1 From 1b66c148cce2699c3f5e470fa82f0efb192eb00a Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 19 Nov 2023 15:55:24 +0100 Subject: UAC2: Implement feedback by fifo counting. --- src/class/audio/audio_device.c | 169 +++++++++++++++++++++++++++-------------- src/class/audio/audio_device.h | 11 +-- 2 files changed, 114 insertions(+), 66 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 9ba38a20c..4ca95d4e7 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2020 Reinhard Panhuber, Jerzy Kasenberg + * Copyright (c) 2023 HiFiPhile * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -319,7 +320,8 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP struct { - CFG_TUSB_MEM_ALIGN uint32_t value; // Feedback value for asynchronous mode (in 16.16 format). + CFG_TUSB_MEM_ALIGN uint32_t send_buf; + uint32_t value; // Feedback value for asynchronous mode (in 16.16 format). uint32_t min_value; // min value according to UAC2 FMT-2.0 section 2.3.1.1. uint32_t max_value; // max value according to UAC2 FMT-2.0 section 2.3.1.1. @@ -335,12 +337,12 @@ typedef struct uint32_t mclk_freq; }fixed; -#if 0 // implement later struct { - uint32_t nominal_value; - uint32_t threshold_bytes; + uint32_t nom_value; // In 16.16 format + uint32_t fifo_lvl_avg; // In 16.16 format + uint16_t fifo_lvl_thr; // fifo level threshold + uint16_t rate_const[2]; // pre-computed feedback/fifo_depth rate }fifo_count; -#endif }compute; } feedback; @@ -473,7 +475,8 @@ static uint16_t audiod_tx_packet_size(const uint16_t* norminal_size, uint16_t da #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -static bool set_fb_params_freq(audiod_function_t* audio, uint32_t sample_freq, uint32_t mclk_freq); +static bool audiod_set_fb_params_freq(audiod_function_t* audio, uint32_t sample_freq, uint32_t mclk_freq); +static void audiod_fb_fifo_count_update(audiod_function_t* audio, uint16_t lvl_new); #endif bool tud_audio_n_mounted(uint8_t func_id) @@ -566,7 +569,7 @@ static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t TU_VERIFY(tud_audio_rx_done_pre_read_cb(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->alt_setting[idxItf])); } -#if CFG_TUD_AUDIO_ENABLE_DECODING && CFG_TUD_AUDIO_ENABLE_EP_OUT +#if CFG_TUD_AUDIO_ENABLE_DECODING switch (audio->format_type_rx) { @@ -615,6 +618,13 @@ static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_out, &audio->ep_out_ff, audio->ep_out_sz), false); #endif +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + if(audio->feedback.compute_method == AUDIO_FEEDBACK_METHOD_FIFO_COUNT) + { + audiod_fb_fifo_count_update(audio, tu_fifo_count(&audio->ep_out_ff)); + } +#endif + #endif // Call a weak callback here - a possibility for user to get informed decoding was completed @@ -725,6 +735,13 @@ static bool audiod_decode_type_I_pcm(uint8_t rhport, audiod_function_t* audio, u // Number of bytes should be a multiple of CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_N_CHANNELS_RX but checking makes no sense - no way to correct it // TU_VERIFY(cnt != n_bytes); +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + if(audio->feedback.compute_method == AUDIO_FEEDBACK_METHOD_FIFO_COUNT) + { + audiod_fb_fifo_count_update(audio, tu_fifo_count(&audio->rx_supp_ff[0])); + } +#endif + return true; } #endif //CFG_TUD_AUDIO_ENABLE_DECODING @@ -1067,9 +1084,29 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi // This function is called once a transmit of a feedback packet was successfully completed. Here, we get the next feedback value to be sent #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -static inline bool audiod_fb_send(uint8_t rhport, audiod_function_t *audio) +static inline bool audiod_fb_send(audiod_function_t *audio) { - return usbd_edpt_xfer(rhport, audio->ep_fb, (uint8_t *) &audio->feedback.value, 4); + // Format the feedback value +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION + if ( TUSB_SPEED_FULL == tud_speed_get() ) + { + uint8_t * fb = (uint8_t *) &audio->feedback.send_buf; + + // For FS format is 10.14 + *(fb++) = (audio->feedback.value >> 2) & 0xFF; + *(fb++) = (audio->feedback.value >> 10) & 0xFF; + *(fb++) = (audio->feedback.value >> 18) & 0xFF; + // 4th byte is needed to work correctly with MS Windows + *fb = 0; + } else + { + value = audio->feedback.value; + } +#else + audio->feedback.send_buf = audio->feedback.value; +#endif + + return usbd_edpt_xfer(audio->rhport, audio->ep_fb, (uint8_t *) &audio->feedback.send_buf, 4); } #endif @@ -1861,7 +1898,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000; - audio->feedback.min_value = (fb_param.sample_freq/frame_div - 1) << 16; + audio->feedback.min_value = ((fb_param.sample_freq - 1)/frame_div) << 16; audio->feedback.max_value = (fb_param.sample_freq/frame_div + 1) << 16; switch(fb_param.method) @@ -1869,20 +1906,27 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED: case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT: case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2: - set_fb_params_freq(audio, fb_param.sample_freq, fb_param.frequency.mclk_freq); + audiod_set_fb_params_freq(audio, fb_param.sample_freq, fb_param.frequency.mclk_freq); break; - #if 0 // implement later case AUDIO_FEEDBACK_METHOD_FIFO_COUNT: { - uint64_t fb64 = ((uint64_t) fb_param.sample_freq) << 16; - audio->feedback.compute.fifo_count.nominal_value = (uint32_t) (fb64 / frame_div); - audio->feedback.compute.fifo_count.threshold_bytes = fb_param.fifo_count.threshold_bytes; - - tud_audio_fb_set(audio->feedback.compute.fifo_count.nominal_value); + /* Initialize the threshold level to half filled */ + uint16_t fifo_lvl_thr; +#if CFG_TUD_AUDIO_ENABLE_DECODING + fifo_lvl_thr = tu_fifo_depth(&audio->rx_supp_ff[0]) / 2; +#else + fifo_lvl_thr = tu_fifo_depth(&audio->ep_out_ff) / 2; +#endif + audio->feedback.compute.fifo_count.fifo_lvl_thr = fifo_lvl_thr; + audio->feedback.compute.fifo_count.fifo_lvl_avg = ((uint32_t)fifo_lvl_thr) << 16; + /* Avoid 64bit division */ + uint32_t nominal = ((fb_param.sample_freq / 100) << 16) / (frame_div / 100); + audio->feedback.compute.fifo_count.nom_value = nominal; + audio->feedback.compute.fifo_count.rate_const[0] = (audio->feedback.max_value - nominal) / fifo_lvl_thr; + audio->feedback.compute.fifo_count.rate_const[1] = (nominal - audio->feedback.min_value) / fifo_lvl_thr; } break; - #endif // nothing to do default: break; @@ -2198,7 +2242,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 if (!usbd_edpt_busy(rhport, audio->ep_fb)) { // Schedule next transmission - value is changed bytud_audio_n_fb_set() in the meantime or the old value gets sent - return audiod_fb_send(rhport, audio); + return audiod_fb_send(audio); } } #endif @@ -2210,7 +2254,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -static bool set_fb_params_freq(audiod_function_t* audio, uint32_t sample_freq, uint32_t mclk_freq) +static bool audiod_set_fb_params_freq(audiod_function_t* audio, uint32_t sample_freq, uint32_t mclk_freq) { // Check if frame interval is within sane limits // The interval value n_frames was taken from the descriptors within audiod_set_interface() @@ -2244,6 +2288,38 @@ static bool set_fb_params_freq(audiod_function_t* audio, uint32_t sample_freq, u return true; } +static void audiod_fb_fifo_count_update(audiod_function_t* audio, uint16_t lvl_new) +{ + /* Low-pass (averaging) filter */ + uint32_t lvl = audio->feedback.compute.fifo_count.fifo_lvl_avg; + lvl = (uint32_t)(((uint64_t)lvl * 63 + ((uint32_t)lvl_new << 16)) >> 6); + audio->feedback.compute.fifo_count.fifo_lvl_avg = lvl; + + uint32_t const ff_lvl = lvl >> 16; + uint16_t const ff_thr = audio->feedback.compute.fifo_count.fifo_lvl_thr; + uint16_t const *rate = audio->feedback.compute.fifo_count.rate_const; + + uint32_t feedback; + + if(ff_lvl < ff_thr) + { + feedback = audio->feedback.compute.fifo_count.nom_value + (ff_thr - ff_lvl) * rate[0]; + } else + { + feedback = audio->feedback.compute.fifo_count.nom_value - (ff_lvl - ff_thr) * rate[1]; + } + + if ( feedback > audio->feedback.max_value ) feedback = audio->feedback.max_value; + if ( feedback < audio->feedback.min_value ) feedback = audio->feedback.min_value; + audio->feedback.value = feedback; + + // Schedule a transmit with the new value if EP is not busy - this triggers repetitive scheduling of the feedback value + if (!usbd_edpt_busy(audio->rhport, audio->ep_fb)) + { + audiod_fb_send(audio); + } +} + uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) { audiod_function_t* audio = &_audiod_fct[func_id]; @@ -2280,6 +2356,21 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) return feedback; } + +bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) +{ + TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); + + _audiod_fct[func_id].feedback.value = feedback; + + // Schedule a transmit with the new value if EP is not busy - this triggers repetitive scheduling of the feedback value + if (!usbd_edpt_busy(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_fb)) + { + return audiod_fb_send(&_audiod_fct[func_id]); + } + + return true; +} #endif TU_ATTR_FAST_FUNC void audiod_sof_isr (uint8_t rhport, uint32_t frame_count) @@ -2691,44 +2782,8 @@ static uint16_t audiod_tx_packet_size(const uint16_t* norminal_size, uint16_t da #endif -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - -bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) -{ - TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); - - // Format the feedback value -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION - if ( TUSB_SPEED_FULL == tud_speed_get() ) - { - uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].feedback.value; - - // For FS format is 10.14 - *(fb++) = (feedback >> 2) & 0xFF; - *(fb++) = (feedback >> 10) & 0xFF; - *(fb++) = (feedback >> 18) & 0xFF; - // 4th byte is needed to work correctly with MS Windows - *fb = 0; - }else -#else - { - // Send value as-is, caller will choose the appropriate format - _audiod_fct[func_id].feedback.value = feedback; - } -#endif - - // Schedule a transmit with the new value if EP is not busy - this triggers repetitive scheduling of the feedback value - if (!usbd_edpt_busy(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_fb)) - { - return audiod_fb_send(_audiod_fct[func_id].rhport, &_audiod_fct[func_id]); - } - - return true; -} -#endif - // No security checks here - internal function only which should always succeed -uint8_t audiod_get_audio_fct_idx(audiod_function_t * audio) +static uint8_t audiod_get_audio_fct_idx(audiod_function_t * audio) { for (uint8_t cnt=0; cnt < CFG_TUD_AUDIO; cnt++) { diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index b16514fd4..9c95ce1a9 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -3,6 +3,7 @@ * * Copyright (c) 2020 Ha Thach (tinyusb.org) * Copyright (c) 2020 Reinhard Panhuber + * Copyright (c) 2023 HiFiPhile * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -487,7 +488,6 @@ TU_ATTR_WEAK void tud_audio_fb_done_cb(uint8_t func_id); // feedback = n_cycles / n_frames * f_s / f_m in 16.16 format, where n_cycles are the number of main clock cycles within fb_n_frames bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); -static inline bool tud_audio_fb_set(uint32_t feedback); // Update feedback value with passed cycles since last time this update function is called. // Typically called within tud_audio_sof_isr(). Required tud_audio_feedback_params_cb() is implemented @@ -500,9 +500,7 @@ enum { AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED, AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT, AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2, - - // impelemnt later - // AUDIO_FEEDBACK_METHOD_FIFO_COUNT + AUDIO_FEEDBACK_METHOD_FIFO_COUNT }; typedef struct { @@ -514,11 +512,6 @@ typedef struct { uint32_t mclk_freq; // Main clock frequency in Hz i.e. master clock to which sample clock is based on }frequency; -#if 0 // implement later - struct { - uint32_t threshold_bytes; // minimum number of bytes received to be considered as filled/ready - }fifo_count; -#endif }; }audio_feedback_params_t; -- cgit v1.3.1 From 187c3793315c422b99368d51204fa2b5acee93da Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 24 Mar 2024 13:53:34 +0100 Subject: Add tu_static to global variables. --- src/class/audio/audio_device.c | 86 +++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 4ca95d4e7..16ba7fe65 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -119,23 +119,23 @@ // EP IN software buffers and mutexes #if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING #if CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 0 - IN_SW_BUF_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ]; + tu_static IN_SW_BUF_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ]; #if CFG_FIFO_MUTEX - osal_mutex_def_t ep_in_ff_mutex_wr_1; // No need for read mutex as only USB driver reads from FIFO + tu_static osal_mutex_def_t ep_in_ff_mutex_wr_1; // No need for read mutex as only USB driver reads from FIFO #endif #endif // CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 0 #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ > 0 - IN_SW_BUF_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ]; + tu_static IN_SW_BUF_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ]; #if CFG_FIFO_MUTEX - osal_mutex_def_t ep_in_ff_mutex_wr_2; // No need for read mutex as only USB driver reads from FIFO + tu_static osal_mutex_def_t ep_in_ff_mutex_wr_2; // No need for read mutex as only USB driver reads from FIFO #endif #endif // CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ > 0 #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ > 0 - IN_SW_BUF_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ]; + tu_static IN_SW_BUF_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ]; #if CFG_FIFO_MUTEX - osal_mutex_def_t ep_in_ff_mutex_wr_3; // No need for read mutex as only USB driver reads from FIFO + tu_static osal_mutex_def_t ep_in_ff_mutex_wr_3; // No need for read mutex as only USB driver reads from FIFO #endif #endif // CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ > 0 #endif // CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING @@ -145,38 +145,38 @@ // - the software encoding is used - in this case the linear buffers serve as a target memory where logical channels are encoded into #if CFG_TUD_AUDIO_ENABLE_EP_IN && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_ENCODING) #if CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX > 0 - CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX]; + tu_static CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX]; #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX > 0 - CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX]; + tu_static CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX]; #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX > 0 - CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX]; + tu_static CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX]; #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_IN && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING) // EP OUT software buffers and mutexes #if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_AUDIO_ENABLE_DECODING #if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0 - OUT_SW_BUF_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ]; + tu_static OUT_SW_BUF_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ]; #if CFG_FIFO_MUTEX - osal_mutex_def_t ep_out_ff_mutex_rd_1; // No need for write mutex as only USB driver writes into FIFO + tu_static osal_mutex_def_t ep_out_ff_mutex_rd_1; // No need for write mutex as only USB driver writes into FIFO #endif #endif // CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0 #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ > 0 - OUT_SW_BUF_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ]; + tu_static OUT_SW_BUF_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ]; #if CFG_FIFO_MUTEX - osal_mutex_def_t ep_out_ff_mutex_rd_2; // No need for write mutex as only USB driver writes into FIFO + tu_static osal_mutex_def_t ep_out_ff_mutex_rd_2; // No need for write mutex as only USB driver writes into FIFO #endif #endif // CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ > 0 #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ > 0 - OUT_SW_BUF_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ]; + tu_static OUT_SW_BUF_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ]; #if CFG_FIFO_MUTEX - osal_mutex_def_t ep_out_ff_mutex_rd_3; // No need for write mutex as only USB driver writes into FIFO + tu_static osal_mutex_def_t ep_out_ff_mutex_rd_3; // No need for write mutex as only USB driver writes into FIFO #endif #endif // CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ > 0 #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_AUDIO_ENABLE_DECODING @@ -186,89 +186,89 @@ // - the software encoding is used - in this case the linear buffers serve as a target memory where logical channels are encoded into #if CFG_TUD_AUDIO_ENABLE_EP_OUT && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING) #if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX > 0 - CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX]; + tu_static CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX]; #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX > 0 - CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX]; + tu_static CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX]; #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX > 0 - CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX]; + tu_static CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX]; #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING) // Control buffers -CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_1[CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ]; +tu_static CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_1[CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ]; #if CFG_TUD_AUDIO > 1 -CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_2[CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ]; +tu_static CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_2[CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ]; #endif #if CFG_TUD_AUDIO > 2 -CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_3[CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ]; +tu_static CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_3[CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ]; #endif // Active alternate setting of interfaces -uint8_t alt_setting_1[CFG_TUD_AUDIO_FUNC_1_N_AS_INT]; +tu_static uint8_t alt_setting_1[CFG_TUD_AUDIO_FUNC_1_N_AS_INT]; #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_N_AS_INT > 0 -uint8_t alt_setting_2[CFG_TUD_AUDIO_FUNC_2_N_AS_INT]; +tu_static uint8_t alt_setting_2[CFG_TUD_AUDIO_FUNC_2_N_AS_INT]; #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_N_AS_INT > 0 -uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT]; +tu_static uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT]; #endif // Software encoding/decoding support FIFOs #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING #if CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ > 0 - CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ]; - tu_fifo_t tx_supp_ff_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO]; + tu_static CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ]; + tu_static tu_fifo_t tx_supp_ff_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO]; #if CFG_FIFO_MUTEX - osal_mutex_def_t tx_supp_ff_mutex_wr_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO + tu_static osal_mutex_def_t tx_supp_ff_mutex_wr_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO #endif #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ > 0 - CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ]; - tu_fifo_t tx_supp_ff_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO]; + tu_static CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ]; + tu_static tu_fifo_t tx_supp_ff_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO]; #if CFG_FIFO_MUTEX - osal_mutex_def_t tx_supp_ff_mutex_wr_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO + tu_static osal_mutex_def_t tx_supp_ff_mutex_wr_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO #endif #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ > 0 - CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ]; - tu_fifo_t tx_supp_ff_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO]; + tu_static CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ]; + tu_static tu_fifo_t tx_supp_ff_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO]; #if CFG_FIFO_MUTEX - osal_mutex_def_t tx_supp_ff_mutex_wr_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO + tu_static osal_mutex_def_t tx_supp_ff_mutex_wr_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO #endif #endif #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING #if CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ > 0 - CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ]; - tu_fifo_t rx_supp_ff_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO]; + tu_static CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ]; + tu_static tu_fifo_t rx_supp_ff_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO]; #if CFG_FIFO_MUTEX - osal_mutex_def_t rx_supp_ff_mutex_rd_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO + tu_static osal_mutex_def_t rx_supp_ff_mutex_rd_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO #endif #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ > 0 - CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ]; - tu_fifo_t rx_supp_ff_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO]; + tu_static CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ]; + tu_static tu_fifo_t rx_supp_ff_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO]; #if CFG_FIFO_MUTEX - osal_mutex_def_t rx_supp_ff_mutex_rd_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO + tu_static osal_mutex_def_t rx_supp_ff_mutex_rd_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO #endif #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ > 0 - CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ]; - tu_fifo_t rx_supp_ff_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO]; + tu_static CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ]; + tu_static tu_fifo_t rx_supp_ff_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO]; #if CFG_FIFO_MUTEX - osal_mutex_def_t rx_supp_ff_mutex_rd_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO + tu_static osal_mutex_def_t rx_supp_ff_mutex_rd_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO #endif #endif #endif @@ -432,7 +432,7 @@ typedef struct //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -CFG_TUD_MEM_SECTION audiod_function_t _audiod_fct[CFG_TUD_AUDIO]; +tu_static CFG_TUD_MEM_SECTION audiod_function_t _audiod_fct[CFG_TUD_AUDIO]; #if CFG_TUD_AUDIO_ENABLE_EP_OUT static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t n_bytes_received); -- cgit v1.3.1 From 02e129a38e14f0be1944290b6e68fafc571b0562 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 23 Mar 2024 18:04:56 +0100 Subject: Guard ep_fb with usbd_edpt_claim(). --- src/class/audio/audio_device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 16ba7fe65..dd82d54ac 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2239,7 +2239,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 if (tud_audio_fb_done_cb) tud_audio_fb_done_cb(func_id); // Schedule a transmit with the new value if EP is not busy - if (!usbd_edpt_busy(rhport, audio->ep_fb)) + if (usbd_edpt_claim(rhport, audio->ep_fb)) { // Schedule next transmission - value is changed bytud_audio_n_fb_set() in the meantime or the old value gets sent return audiod_fb_send(audio); @@ -2314,7 +2314,7 @@ static void audiod_fb_fifo_count_update(audiod_function_t* audio, uint16_t lvl_n audio->feedback.value = feedback; // Schedule a transmit with the new value if EP is not busy - this triggers repetitive scheduling of the feedback value - if (!usbd_edpt_busy(audio->rhport, audio->ep_fb)) + if (usbd_edpt_claim(audio->rhport, audio->ep_fb)) { audiod_fb_send(audio); } @@ -2364,7 +2364,7 @@ bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) _audiod_fct[func_id].feedback.value = feedback; // Schedule a transmit with the new value if EP is not busy - this triggers repetitive scheduling of the feedback value - if (!usbd_edpt_busy(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_fb)) + if (usbd_edpt_claim(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_fb)) { return audiod_fb_send(&_audiod_fct[func_id]); } -- cgit v1.3.1 From f2d455226ac7b83dfd1e7ef56124e6fecfc4a40e Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 19 Nov 2023 23:46:00 +0100 Subject: Add UAC2 speaker with feedback example. --- examples/device/uac2_speaker_fb/CMakeLists.txt | 33 ++ examples/device/uac2_speaker_fb/Makefile | 11 + examples/device/uac2_speaker_fb/skip.txt | 8 + examples/device/uac2_speaker_fb/src/audio_debug.py | 63 +++ examples/device/uac2_speaker_fb/src/common_types.h | 52 +++ examples/device/uac2_speaker_fb/src/main.c | 478 +++++++++++++++++++++ examples/device/uac2_speaker_fb/src/tusb_config.h | 157 +++++++ .../device/uac2_speaker_fb/src/usb_descriptors.c | 234 ++++++++++ .../device/uac2_speaker_fb/src/usb_descriptors.h | 82 ++++ 9 files changed, 1118 insertions(+) create mode 100644 examples/device/uac2_speaker_fb/CMakeLists.txt create mode 100644 examples/device/uac2_speaker_fb/Makefile create mode 100644 examples/device/uac2_speaker_fb/skip.txt create mode 100644 examples/device/uac2_speaker_fb/src/audio_debug.py create mode 100644 examples/device/uac2_speaker_fb/src/common_types.h create mode 100644 examples/device/uac2_speaker_fb/src/main.c create mode 100644 examples/device/uac2_speaker_fb/src/tusb_config.h create mode 100644 examples/device/uac2_speaker_fb/src/usb_descriptors.c create mode 100644 examples/device/uac2_speaker_fb/src/usb_descriptors.h diff --git a/examples/device/uac2_speaker_fb/CMakeLists.txt b/examples/device/uac2_speaker_fb/CMakeLists.txt new file mode 100644 index 000000000..e92a57148 --- /dev/null +++ b/examples/device/uac2_speaker_fb/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.17) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) + +# gets PROJECT name for the example (e.g. -) +family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) + +project(${PROJECT} C CXX ASM) + +# Checks this example is valid for the family and initializes the project +family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) + +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + +add_executable(${PROJECT}) + +# Example source +target_sources(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c + ) + +# Example include +target_include_directories(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src + ) + +# Configure compilation flags and libraries for the example without RTOS. +# See the corresponding function in hw/bsp/FAMILY/family.cmake for details. +family_configure_device_example(${PROJECT} noos) diff --git a/examples/device/uac2_speaker_fb/Makefile b/examples/device/uac2_speaker_fb/Makefile new file mode 100644 index 000000000..7fa475da5 --- /dev/null +++ b/examples/device/uac2_speaker_fb/Makefile @@ -0,0 +1,11 @@ +include ../../build_system/make/make.mk + +INC += \ + src \ + $(TOP)/hw \ + +# Example source +EXAMPLE_SOURCE += $(wildcard src/*.c) +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +include ../../build_system/make/rules.mk diff --git a/examples/device/uac2_speaker_fb/skip.txt b/examples/device/uac2_speaker_fb/skip.txt new file mode 100644 index 000000000..234f1ebed --- /dev/null +++ b/examples/device/uac2_speaker_fb/skip.txt @@ -0,0 +1,8 @@ +mcu:LPC11UXX +mcu:LPC13XX +mcu:NUC121 +mcu:SAMD11 +mcu:SAME5X +mcu:SAMG +board:stm32l052dap52 +family:broadcom_64bit diff --git a/examples/device/uac2_speaker_fb/src/audio_debug.py b/examples/device/uac2_speaker_fb/src/audio_debug.py new file mode 100644 index 000000000..182d6ca89 --- /dev/null +++ b/examples/device/uac2_speaker_fb/src/audio_debug.py @@ -0,0 +1,63 @@ +# Install python3 HID package https://pypi.org/project/hid/ +import hid +from ctypes import * +import matplotlib.pyplot as plt +import matplotlib.animation as animation + +# Example must be compiled with CFG_AUDIO_DEBUG=1 +VID = 0xcafe +PID = 0x4014 + +CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX = 2 + +class audio_debug_info_t (Structure): + _fields_ = [("sample_rate", c_uint32), + ("alt_settings", c_uint8), + ("mute", (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1) * c_int8), + ("volume", (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1) * c_int16), + ("fifo_size", c_uint16), + ("fifo_count", c_uint16), + ("fifo_count_avg", c_uint16) + ] + +dev = hid.Device(VID, PID) + +if dev: + # Create figure for plotting + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1) + fifo_avg = [] + fifo_cnt = [] + # This function is called periodically from FuncAnimation + def animate(i): + info = None + for i in range(30): + str_in = dev.read(64, 10) + if str_in: + info = audio_debug_info_t.from_buffer_copy(str_in) + + global fifo_avg + global fifo_cnt + fifo_avg.append(info.fifo_count_avg) + fifo_cnt.append(info.fifo_count) + + # Limit to 1000 items + fifo_avg = fifo_avg[-1000:] + fifo_cnt = fifo_cnt[-1000:] + + if info is not None: + # Draw x and y lists + ax.clear() + ax.plot(fifo_cnt, label='FIFO count') + ax.plot(fifo_avg, label='FIFO average') + ax.legend() + ax.set_ylim(bottom=0, top=info.fifo_size) + + # Format plot + plt.title('FIFO information') + plt.grid() + + print(f'Sample rate:{info.sample_rate} | Alt settings:{info.alt_settings} | Volume:{info.volume[:]}') + + ani = animation.FuncAnimation(fig, animate, interval=10) + plt.show() diff --git a/examples/device/uac2_speaker_fb/src/common_types.h b/examples/device/uac2_speaker_fb/src/common_types.h new file mode 100644 index 000000000..174e26671 --- /dev/null +++ b/examples/device/uac2_speaker_fb/src/common_types.h @@ -0,0 +1,52 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 HiFiPhile + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _COMMON_TYPES_H_ +#define _COMMON_TYPES_H_ + +enum +{ + ITF_NUM_AUDIO_CONTROL = 0, + ITF_NUM_AUDIO_STREAMING, +#if CFG_AUDIO_DEBUG + ITF_NUM_DEBUG, +#endif + ITF_NUM_TOTAL +}; + +#if CFG_AUDIO_DEBUG +typedef struct + { + uint32_t sample_rate; + uint8_t alt_settings; + int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; + int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; + uint16_t fifo_size; + uint16_t fifo_count; + uint16_t fifo_count_avg; + } audio_debug_info_t; +#endif + +#endif diff --git a/examples/device/uac2_speaker_fb/src/main.c b/examples/device/uac2_speaker_fb/src/main.c new file mode 100644 index 000000000..6d0e7acff --- /dev/null +++ b/examples/device/uac2_speaker_fb/src/main.c @@ -0,0 +1,478 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Jerzy Kasenberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include +#include + +#include "bsp/board_api.h" +#include "tusb.h" +#include "usb_descriptors.h" +#include "common_types.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTOTYPES +//--------------------------------------------------------------------+ + +// List of supported sample rates +#if defined(__RX__) + const uint32_t sample_rates[] = {44100, 48000}; +#else + const uint32_t sample_rates[] = {44100, 48000, 88200, 96000}; +#endif + +uint32_t current_sample_rate = 44100; + +#define N_SAMPLE_RATES TU_ARRAY_SIZE(sample_rates) + +/* Blink pattern + * - 25 ms : streaming data + * - 250 ms : device not mounted + * - 1000 ms : device mounted + * - 2500 ms : device is suspended + */ +enum +{ + BLINK_STREAMING = 25, + BLINK_NOT_MOUNTED = 250, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, +}; + +enum +{ + VOLUME_CTRL_0_DB = 0, + VOLUME_CTRL_10_DB = 2560, + VOLUME_CTRL_20_DB = 5120, + VOLUME_CTRL_30_DB = 7680, + VOLUME_CTRL_40_DB = 10240, + VOLUME_CTRL_50_DB = 12800, + VOLUME_CTRL_60_DB = 15360, + VOLUME_CTRL_70_DB = 17920, + VOLUME_CTRL_80_DB = 20480, + VOLUME_CTRL_90_DB = 23040, + VOLUME_CTRL_100_DB = 25600, + VOLUME_CTRL_SILENCE = 0x8000, +}; + +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; + +// Audio controls +// Current states +int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0 +int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0 + +// Buffer for speaker data +uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ/2]; + +void led_blinking_task(void); +void audio_task(void); + +#if CFG_AUDIO_DEBUG +void audio_debug_task(void); +uint8_t current_alt_settings; +#endif + +/*------------- MAIN -------------*/ +int main(void) +{ + board_init(); + + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); + + if (board_init_after_tusb) { + board_init_after_tusb(); + } + + TU_LOG1("Speaker running\r\n"); + + while (1) + { + tud_task(); // TinyUSB device task + led_blinking_task(); +#if CFG_AUDIO_DEBUG + audio_debug_task(); +#endif + audio_task(); + } +} + +//--------------------------------------------------------------------+ +// Device callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +void tud_mount_cb(void) +{ + blink_interval_ms = BLINK_MOUNTED; +} + +// Invoked when device is unmounted +void tud_umount_cb(void) +{ + blink_interval_ms = BLINK_NOT_MOUNTED; +} + +// Invoked when usb bus is suspended +// remote_wakeup_en : if host allow us to perform remote wakeup +// Within 7ms, device must draw an average of current less than 2.5 mA from bus +void tud_suspend_cb(bool remote_wakeup_en) +{ + (void)remote_wakeup_en; + blink_interval_ms = BLINK_SUSPENDED; +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) +{ + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; +} + +//--------------------------------------------------------------------+ +// Application Callback API Implementations +//--------------------------------------------------------------------+ + +// Helper for clock get requests +static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t const *request) +{ + TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); + + if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) + { + if (request->bRequest == AUDIO_CS_REQ_CUR) + { + TU_LOG1("Clock get current freq %lu\r\n", current_sample_rate); + + audio_control_cur_4_t curf = { (int32_t) tu_htole32(current_sample_rate) }; + return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &curf, sizeof(curf)); + } + else if (request->bRequest == AUDIO_CS_REQ_RANGE) + { + audio_control_range_4_n_t(N_SAMPLE_RATES) rangef = + { + .wNumSubRanges = tu_htole16(N_SAMPLE_RATES) + }; + TU_LOG1("Clock get %d freq ranges\r\n", N_SAMPLE_RATES); + for(uint8_t i = 0; i < N_SAMPLE_RATES; i++) + { + rangef.subrange[i].bMin = (int32_t) sample_rates[i]; + rangef.subrange[i].bMax = (int32_t) sample_rates[i]; + rangef.subrange[i].bRes = 0; + TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int)rangef.subrange[i].bMin, (int)rangef.subrange[i].bMax, (int)rangef.subrange[i].bRes); + } + + return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &rangef, sizeof(rangef)); + } + } + else if (request->bControlSelector == AUDIO_CS_CTRL_CLK_VALID && + request->bRequest == AUDIO_CS_REQ_CUR) + { + audio_control_cur_1_t cur_valid = { .bCur = 1 }; + TU_LOG1("Clock get is valid %u\r\n", cur_valid.bCur); + return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_valid, sizeof(cur_valid)); + } + TU_LOG1("Clock get request not supported, entity = %u, selector = %u, request = %u\r\n", + request->bEntityID, request->bControlSelector, request->bRequest); + return false; +} + +// Helper for clock set requests +static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf) +{ + (void)rhport; + + TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); + TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR); + + if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) + { + TU_VERIFY(request->wLength == sizeof(audio_control_cur_4_t)); + + current_sample_rate = (uint32_t) ((audio_control_cur_4_t const *)buf)->bCur; + + TU_LOG1("Clock set current freq: %ld\r\n", current_sample_rate); + + return true; + } + else + { + TU_LOG1("Clock set request not supported, entity = %u, selector = %u, request = %u\r\n", + request->bEntityID, request->bControlSelector, request->bRequest); + return false; + } +} + +// Helper for feature unit get requests +static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_request_t const *request) +{ + TU_ASSERT(request->bEntityID == UAC2_ENTITY_FEATURE_UNIT); + + if (request->bControlSelector == AUDIO_FU_CTRL_MUTE && request->bRequest == AUDIO_CS_REQ_CUR) + { + audio_control_cur_1_t mute1 = { .bCur = mute[request->bChannelNumber] }; + TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur); + return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &mute1, sizeof(mute1)); + } + else if (UAC2_ENTITY_FEATURE_UNIT && request->bControlSelector == AUDIO_FU_CTRL_VOLUME) + { + if (request->bRequest == AUDIO_CS_REQ_RANGE) + { + audio_control_range_2_n_t(1) range_vol = { + .wNumSubRanges = tu_htole16(1), + .subrange[0] = { .bMin = tu_htole16(-VOLUME_CTRL_50_DB), tu_htole16(VOLUME_CTRL_0_DB), tu_htole16(256) } + }; + TU_LOG1("Get channel %u volume range (%d, %d, %u) dB\r\n", request->bChannelNumber, + range_vol.subrange[0].bMin / 256, range_vol.subrange[0].bMax / 256, range_vol.subrange[0].bRes / 256); + return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &range_vol, sizeof(range_vol)); + } + else if (request->bRequest == AUDIO_CS_REQ_CUR) + { + audio_control_cur_2_t cur_vol = { .bCur = tu_htole16(volume[request->bChannelNumber]) }; + TU_LOG1("Get channel %u volume %d dB\r\n", request->bChannelNumber, cur_vol.bCur / 256); + return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_vol, sizeof(cur_vol)); + } + } + TU_LOG1("Feature unit get request not supported, entity = %u, selector = %u, request = %u\r\n", + request->bEntityID, request->bControlSelector, request->bRequest); + + return false; +} + +// Helper for feature unit set requests +static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf) +{ + (void)rhport; + + TU_ASSERT(request->bEntityID == UAC2_ENTITY_FEATURE_UNIT); + TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR); + + if (request->bControlSelector == AUDIO_FU_CTRL_MUTE) + { + TU_VERIFY(request->wLength == sizeof(audio_control_cur_1_t)); + + mute[request->bChannelNumber] = ((audio_control_cur_1_t const *)buf)->bCur; + + TU_LOG1("Set channel %d Mute: %d\r\n", request->bChannelNumber, mute[request->bChannelNumber]); + + return true; + } + else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME) + { + TU_VERIFY(request->wLength == sizeof(audio_control_cur_2_t)); + + volume[request->bChannelNumber] = ((audio_control_cur_2_t const *)buf)->bCur; + + TU_LOG1("Set channel %d volume: %d dB\r\n", request->bChannelNumber, volume[request->bChannelNumber] / 256); + + return true; + } + else + { + TU_LOG1("Feature unit set request not supported, entity = %u, selector = %u, request = %u\r\n", + request->bEntityID, request->bControlSelector, request->bRequest); + return false; + } +} + +// Invoked when audio class specific get request received for an entity +bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) +{ + audio_control_request_t const *request = (audio_control_request_t const *)p_request; + + if (request->bEntityID == UAC2_ENTITY_CLOCK) + return tud_audio_clock_get_request(rhport, request); + if (request->bEntityID == UAC2_ENTITY_FEATURE_UNIT) + return tud_audio_feature_unit_get_request(rhport, request); + else + { + TU_LOG1("Get request not handled, entity = %d, selector = %d, request = %d\r\n", + request->bEntityID, request->bControlSelector, request->bRequest); + } + return false; +} + +// Invoked when audio class specific set request received for an entity +bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf) +{ + audio_control_request_t const *request = (audio_control_request_t const *)p_request; + + if (request->bEntityID == UAC2_ENTITY_FEATURE_UNIT) + return tud_audio_feature_unit_set_request(rhport, request, buf); + if (request->bEntityID == UAC2_ENTITY_CLOCK) + return tud_audio_clock_set_request(rhport, request, buf); + TU_LOG1("Set request not handled, entity = %d, selector = %d, request = %d\r\n", + request->bEntityID, request->bControlSelector, request->bRequest); + + return false; +} + +bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void)rhport; + + uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); + uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); + + if (ITF_NUM_AUDIO_STREAMING == itf && alt == 0) + blink_interval_ms = BLINK_MOUNTED; + + return true; +} + +bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void)rhport; + uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); + uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); + + TU_LOG2("Set interface %d alt %d\r\n", itf, alt); + if (ITF_NUM_AUDIO_STREAMING == itf && alt != 0) + blink_interval_ms = BLINK_STREAMING; + +#if CFG_AUDIO_DEBUG + current_alt_settings = alt; +#endif + + return true; +} + +void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param) +{ + (void)func_id; + (void)alt_itf; + // Set feedback method to fifo counting + feedback_param->method = AUDIO_FEEDBACK_METHOD_FIFO_COUNT; + feedback_param->sample_freq = current_sample_rate; +} + +//--------------------------------------------------------------------+ +// AUDIO Task +//--------------------------------------------------------------------+ + +void audio_task(void) +{ + // Replace audio_task() with your I2S transmit callback. + // Here we simulate a callback called every 1ms. + static uint32_t start_ms = 0; + uint32_t curr_ms = board_millis(); + if ( start_ms == curr_ms ) return; // not enough time + start_ms = curr_ms; + + uint16_t length = current_sample_rate/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX; + + if (current_sample_rate == 44100 && (curr_ms % 10 == 0)) + { + // Take one more sample every 10 cycles, to have a average reading speed of 44.1 + // This correction is not needed in real world cases + length += CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX; + } else + if (current_sample_rate == 88200 && (curr_ms % 5 == 0)) + { + // Take one more sample every 5 cycles, to have a average reading speed of 88.2 + // This correction is not needed in real world cases + length += CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX; + } + + tud_audio_read(i2s_dummy_buffer, length); +} + +//--------------------------------------------------------------------+ +// BLINKING TASK +//--------------------------------------------------------------------+ +void led_blinking_task(void) +{ + static uint32_t start_ms = 0; + static bool led_state = false; + + // Blink every interval ms + if (board_millis() - start_ms < blink_interval_ms) return; + start_ms += blink_interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; +} + +#if CFG_AUDIO_DEBUG +//--------------------------------------------------------------------+ +// HID interface for audio debug +//--------------------------------------------------------------------+ + +// Every 1ms, we will sent 1 debug information report +void audio_debug_task(void) +{ + static uint32_t start_ms = 0; + uint32_t curr_ms = board_millis(); + if ( start_ms == curr_ms ) return; // not enough time + start_ms = curr_ms; + + uint16_t fifo_count = tud_audio_available(); + static uint32_t fifo_count_avg; + + // Same averaging method used in UAC2 class + fifo_count_avg = (uint32_t)(((uint64_t)fifo_count_avg * 63 + ((uint32_t)fifo_count << 16)) >> 6); + + audio_debug_info_t debug_info; + debug_info.sample_rate = current_sample_rate; + debug_info.alt_settings = current_alt_settings; + debug_info.fifo_size = CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ; + debug_info.fifo_count = fifo_count; + debug_info.fifo_count_avg = fifo_count_avg >> 16; + for (int i = 0; i < CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1; i++) + { + debug_info.mute[i] = mute[i]; + debug_info.volume[i] = volume[i]; + } + + if(tud_hid_ready()) + tud_hid_report(0, &debug_info, sizeof(debug_info)); +} + +// Invoked when received GET_REPORT control request +// Unused here +uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) +{ + // TODO not Implemented + (void) itf; + (void) report_id; + (void) report_type; + (void) buffer; + (void) reqlen; + + return 0; +} + +// Invoked when received SET_REPORT control request or +// Unused here +void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) +{ + // This example doesn't use multiple report and report ID + (void) itf; + (void) report_id; + (void) report_type; + (void) buffer; + (void) bufsize; +} + +#endif diff --git a/examples/device/uac2_speaker_fb/src/tusb_config.h b/examples/device/uac2_speaker_fb/src/tusb_config.h new file mode 100644 index 000000000..497104541 --- /dev/null +++ b/examples/device/uac2_speaker_fb/src/tusb_config.h @@ -0,0 +1,157 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Ha Thach (tinyusb.org) + * Copyright (c) 2020 Jerzy Kasenberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "usb_descriptors.h" + +//--------------------------------------------------------------------+ +// Board Specific Configuration +//--------------------------------------------------------------------+ + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_TUD_RHPORT +#define BOARD_TUD_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUD_MAX_SPEED +#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-------------------------------------------------------------------- +// Common Configuration +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU +#error CFG_TUSB_MCU must be defined +#endif + +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_NONE +#endif + +// It's recommended to disable debug unless for control requests debugging, +// as the extra time needed will impact data stream ! +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +// Enable Device stack +#define CFG_TUD_ENABLED 1 + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +// Expose audio class debug information via HID interface +#ifndef CFG_AUDIO_DEBUG +#define CFG_AUDIO_DEBUG 1 +#endif + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +#define CFG_TUD_HID_EP_BUFSIZE 64 + +//------------- CLASS -------------// +#define CFG_TUD_AUDIO 1 + +#if CFG_AUDIO_DEBUG +#define CFG_TUD_HID 1 +#else +#define CFG_TUD_HID 0 +#endif + +#define CFG_TUD_CDC 0 +#define CFG_TUD_MSC 0 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_VENDOR 0 + +//-------------------------------------------------------------------- +// AUDIO CLASS DRIVER CONFIGURATION +//-------------------------------------------------------------------- + +#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_SPEAKER_STEREO_FB_DESC_LEN + +// Audio format type I specifications +#if defined(__RX__) +#define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 48000 +#else +#define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 96000 +#endif + +#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX 2 + +// 16bit in 16bit slots +#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX 2 +#define CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX 16 + +// EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) +#define CFG_TUD_AUDIO_ENABLE_EP_OUT 1 + +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX // Example read FIFO every 1ms, so it should be 8 times larger for HS device + +// Enable feedback EP +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 1 + +// Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes) +#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 + +// Size of control request buffer +#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/uac2_speaker_fb/src/usb_descriptors.c b/examples/device/uac2_speaker_fb/src/usb_descriptors.c new file mode 100644 index 000000000..864b689ff --- /dev/null +++ b/examples/device/uac2_speaker_fb/src/usb_descriptors.c @@ -0,0 +1,234 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 HiFiPhile + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "bsp/board_api.h" +#include "tusb.h" +#include "usb_descriptors.h" +#include "common_types.h" + +/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. + * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. + * + * Auto ProductID layout's Bitmap: + * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] + */ +#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ + _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) ) + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +tusb_desc_device_t const desc_device = +{ + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + + // Use Interface Association Descriptor (IAD) for Audio + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = 0xCafe, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const * tud_descriptor_device_cb(void) +{ + return (uint8_t const *)&desc_device; +} + +#if CFG_AUDIO_DEBUG +//--------------------------------------------------------------------+ +// HID Report Descriptor +//--------------------------------------------------------------------+ + +uint8_t const desc_hid_report[] = +{ + HID_USAGE_PAGE_N ( HID_USAGE_PAGE_VENDOR, 2 ),\ + HID_USAGE ( 0x01 ),\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\ + HID_USAGE ( 0x02 ),\ + HID_LOGICAL_MIN ( 0x00 ),\ + HID_LOGICAL_MAX_N ( 0xff, 2 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT( sizeof(audio_debug_info_t) ),\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END +}; + +// Invoked when received GET HID REPORT DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf) +{ + (void) itf; + return desc_hid_report; +} +#endif + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ + +#if CFG_AUDIO_DEBUG + #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO_SPEAKER_STEREO_FB_DESC_LEN + TUD_HID_DESC_LEN) +#else + #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO_SPEAKER_STEREO_FB_DESC_LEN) +#endif + +#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX + // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number + // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... + #define EPNUM_AUDIO_FB 0x03 + #define EPNUM_AUDIO_OUT 0x03 + #define EPNUM_DEBUG 0x04 + +#elif CFG_TUSB_MCU == OPT_MCU_NRF5X + // ISO endpoints for NRF5x are fixed to 0x08 (0x88) + #define EPNUM_AUDIO_FB 0x08 + #define EPNUM_AUDIO_OUT 0x08 + #define EPNUM_DEBUG 0x01 + +#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X + // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_AUDIO_FB 0x01 + #define EPNUM_AUDIO_OUT 0x02 + #define EPNUM_DEBUG 0x03 + +#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X + // FT9XX doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_AUDIO_FB 0x01 + #define EPNUM_AUDIO_OUT 0x02 + #define EPNUM_DEBUG 0x03 + +#else + #define EPNUM_AUDIO_FB 0x01 + #define EPNUM_AUDIO_OUT 0x01 + #define EPNUM_DEBUG 0x02 +#endif + +uint8_t const desc_configuration[] = +{ + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + + // Interface number, string index, byte per sample, bit per sample, EP Out, EP size, EP feedback + TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR(0, 4, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX, EPNUM_AUDIO_OUT, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX, EPNUM_AUDIO_FB | 0x80), + +#if CFG_AUDIO_DEBUG + // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval + TUD_HID_DESCRIPTOR(ITF_NUM_DEBUG, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_DEBUG | 0x80, CFG_TUD_HID_EP_BUFSIZE, 7) +#endif +}; + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) +{ + (void)index; // for multiple configurations + return desc_configuration; +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +// String Descriptor Index +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, +}; + +// array of pointer to string descriptors +char const *string_desc_arr[] = +{ + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Speaker", // 2: Product + NULL, // 3: Serials will use unique ID if possible + "UAC2 Speaker", // 4: Audio Interface +}; + +static uint16_t _desc_str[32 + 1]; + +// Invoked when received GET STRING DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { + (void) langid; + size_t chr_count; + + switch ( index ) { + case STRID_LANGID: + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + break; + + case STRID_SERIAL: + chr_count = board_usb_get_serial(_desc_str + 1, 32); + break; + + default: + // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. + // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors + + if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + + const char *str = string_desc_arr[index]; + + // Cap at max char + chr_count = strlen(str); + size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type + if ( chr_count > max_count ) chr_count = max_count; + + // Convert ASCII string into UTF-16 + for ( size_t i = 0; i < chr_count; i++ ) { + _desc_str[1 + i] = str[i]; + } + break; + } + + // first byte is length (including header), second byte is string type + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); + + return _desc_str; +} diff --git a/examples/device/uac2_speaker_fb/src/usb_descriptors.h b/examples/device/uac2_speaker_fb/src/usb_descriptors.h new file mode 100644 index 000000000..8157f02a0 --- /dev/null +++ b/examples/device/uac2_speaker_fb/src/usb_descriptors.h @@ -0,0 +1,82 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 HiFiPhile + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _USB_DESCRIPTORS_H_ +#define _USB_DESCRIPTORS_H_ + +// Defined in TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR +#define UAC2_ENTITY_CLOCK 0x04 +#define UAC2_ENTITY_INPUT_TERMINAL 0x01 +#define UAC2_ENTITY_FEATURE_UNIT 0x02 +#define UAC2_ENTITY_OUTPUT_TERMINAL 0x03 + +#define TUD_AUDIO_SPEAKER_STEREO_FB_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN\ + + TUD_AUDIO_DESC_STD_AC_LEN\ + + TUD_AUDIO_DESC_CS_AC_LEN\ + + TUD_AUDIO_DESC_CLK_SRC_LEN\ + + TUD_AUDIO_DESC_INPUT_TERM_LEN\ + + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN\ + + TUD_AUDIO_DESC_STD_AS_INT_LEN\ + + TUD_AUDIO_DESC_STD_AS_INT_LEN\ + + TUD_AUDIO_DESC_CS_AS_INT_LEN\ + + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\ + + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ + + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\ + + TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN) + +#define TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epsize, _epfb) \ + /* Standard Interface Association Descriptor (IAD) */\ + TUD_AUDIO_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ + /* Standard AC Interface Descriptor(4.7.1) */\ + TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ + TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO_FUNC_DESKTOP_SPEAKER, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN, /*_ctrl*/ AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ + /* Clock Source Descriptor(4.7.2.1) */\ + TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO_CLOCK_SOURCE_ATT_INT_PRO_CLK, /*_ctrl*/ (AUDIO_CTRL_RW << AUDIO_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ + /* Input Terminal Descriptor(4.7.2.4) */\ + TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO_CTRL_R << AUDIO_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ + /* Output Terminal Descriptor(4.7.2.5) */\ + TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ + /* Feature Unit Descriptor(4.7.2.8) */\ + TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_ctrlch0master*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS,/*_stridx*/ 0x00),\ + /* Standard AS Interface Descriptor(4.9.1) */\ + /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ + /* Standard AS Interface Descriptor(4.9.1) */\ + /* Interface 1, Alternate 1 - alternate interface for data streaming */\ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x02, /*_stridx*/ 0x00),\ + /* Class-Specific AS Interface Descriptor(4.9.2) */\ + TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x02, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ + /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ + TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ + TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ + /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ + TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_interval*/ TUD_OPT_HIGH_SPEED ? 4 : 1)\ + +#endif -- cgit v1.3.1 From f69255e7355a7cd7c4cd08f50c6f1ba4fc3b5a45 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 19 Nov 2023 23:59:20 +0100 Subject: Fix CI. --- src/portable/wch/dcd_ch32_usbhs.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 1f1c0b876..43cda2566 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -135,6 +135,14 @@ void dcd_remote_wakeup(uint8_t rhport) (void) rhport; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { (void)rhport; -- cgit v1.3.1 From ba27179f173123f50dec5370a6ecd87f059af0e1 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 1 Dec 2023 14:03:43 +0100 Subject: Fix typo. --- examples/device/cdc_uac2/src/uac2_app.c | 2 +- examples/device/uac2_headset/src/main.c | 2 +- examples/device/uac2_speaker_fb/src/main.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/device/cdc_uac2/src/uac2_app.c b/examples/device/cdc_uac2/src/uac2_app.c index c57d98a1a..70b0949a9 100644 --- a/examples/device/cdc_uac2/src/uac2_app.c +++ b/examples/device/cdc_uac2/src/uac2_app.c @@ -141,7 +141,7 @@ static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_req TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &mute1, sizeof(mute1)); } - else if (UAC2_ENTITY_SPK_FEATURE_UNIT && request->bControlSelector == AUDIO_FU_CTRL_VOLUME) + else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME) { if (request->bRequest == AUDIO_CS_REQ_RANGE) { diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index 0ea6e7025..c285211b8 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -229,7 +229,7 @@ static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_req TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &mute1, sizeof(mute1)); } - else if (UAC2_ENTITY_SPK_FEATURE_UNIT && request->bControlSelector == AUDIO_FU_CTRL_VOLUME) + else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME) { if (request->bRequest == AUDIO_CS_REQ_RANGE) { diff --git a/examples/device/uac2_speaker_fb/src/main.c b/examples/device/uac2_speaker_fb/src/main.c index 6d0e7acff..187ff2afe 100644 --- a/examples/device/uac2_speaker_fb/src/main.c +++ b/examples/device/uac2_speaker_fb/src/main.c @@ -235,7 +235,7 @@ static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_req TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &mute1, sizeof(mute1)); } - else if (UAC2_ENTITY_FEATURE_UNIT && request->bControlSelector == AUDIO_FU_CTRL_VOLUME) + else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME) { if (request->bRequest == AUDIO_CS_REQ_RANGE) { -- cgit v1.3.1 From 0a70a66b07cebcdf1716ea0c1b301a6945c13839 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 19 Nov 2023 23:43:36 +0100 Subject: Fix up TUD_AUDIO_SPEAKER_MONO_FB_DESCRIPTOR. --- src/device/usbd.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/usbd.h b/src/device/usbd.h index 0197628e2..17616f7b1 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -561,7 +561,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Output Terminal Descriptor(4.7.2.5) */\ TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ - TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_ctrlch0master*/ 0 * (AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch1*/ 0 * (AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS), /*_stridx*/ 0x00),\ + TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_ctrlch0master*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ @@ -577,7 +577,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_interval*/ 1)\ + TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_interval*/ 1) // Calculate wMaxPacketSize of Endpoints #define TUD_AUDIO_EP_SIZE(_maxFrequency, _nBytesPerSample, _nChannels) \ -- cgit v1.3.1 From a7762ff82e534de0ee07d2701aedeba0e949a94f Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 19 Nov 2023 23:45:02 +0100 Subject: LPC55 : Use PLL clock for better precision, allows easier UAC testing. --- hw/bsp/lpc55/family.c | 85 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 28 deletions(-) diff --git a/hw/bsp/lpc55/family.c b/hw/bsp/lpc55/family.c index cfd5b7032..9cbce7eda 100644 --- a/hw/bsp/lpc55/family.c +++ b/hw/bsp/lpc55/family.c @@ -81,44 +81,73 @@ void USB1_IRQHandler(void) { } /**************************************************************** -name: BOARD_BootClockFROHF96M +name: BOARD_BootClockPLL100M outputs: -- {id: SYSTICK_clock.outFreq, value: 96 MHz} -- {id: System_clock.outFreq, value: 96 MHz} +- {id: System_clock.outFreq, value: 100 MHz} settings: -- {id: SYSCON.MAINCLKSELA.sel, value: SYSCON.fro_hf} +- {id: PLL0_Mode, value: Normal} +- {id: ANALOG_CONTROL_FRO192M_CTRL_ENDI_FRO_96M_CFG, value: Enable} +- {id: ENABLE_CLKIN_ENA, value: Enabled} +- {id: ENABLE_SYSTEM_CLK_OUT, value: Enabled} +- {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL0_BYPASS} +- {id: SYSCON.PLL0CLKSEL.sel, value: SYSCON.CLK_IN_EN} +- {id: SYSCON.PLL0M_MULT.scale, value: '100', locked: true} +- {id: SYSCON.PLL0N_DIV.scale, value: '4', locked: true} +- {id: SYSCON.PLL0_PDEC.scale, value: '4', locked: true} sources: -- {id: SYSCON.fro_hf.outFreq, value: 96 MHz} +- {id: ANACTRL.fro_hf.outFreq, value: 96 MHz} +- {id: SYSCON.XTAL32M.outFreq, value: 16 MHz, enabled: true} ******************************************************************/ -void BootClockFROHF96M(void) { - /*!< Set up the clock sources */ - /*!< Set up FRO */ - POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ - CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ - CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change voltage without - accidentally being below the voltage for current speed */ - - CLOCK_SetupFROClocking(96000000U); /*!< Set up high frequency FRO output to selected frequency */ - - POWER_SetVoltageForFreq(96000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ - CLOCK_SetFLASHAccessCyclesForFreq(96000000U); /*!< Set FLASH wait states for core */ - - /*!< Set up dividers */ - CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ - - /*!< Set up clock selectors - Attach clocks to the peripheries */ - CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ - - /*!< Set SystemCoreClock variable. */ - SystemCoreClock = 96000000U; +void BOARD_BootClockPLL100M(void) +{ + /*!< Set up the clock sources */ + /*!< Configure FRO192M */ + POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ + CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ + + CLOCK_SetupFROClocking(96000000U); /* Enable FRO HF(96MHz) output */ + + /*!< Configure XTAL32M */ + POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */ + POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */ + CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */ + SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */ + ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */ + + POWER_SetVoltageForFreq(100000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ + CLOCK_SetFLASHAccessCyclesForFreq(100000000U); /*!< Set FLASH wait states for core */ + + /*!< Set up PLL */ + CLOCK_AttachClk(kEXT_CLK_to_PLL0); /*!< Switch PLL0CLKSEL to EXT_CLK */ + POWER_DisablePD(kPDRUNCFG_PD_PLL0); /* Ensure PLL is on */ + POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG); + const pll_setup_t pll0Setup = { + .pllctrl = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_SELI(53U) | SYSCON_PLL0CTRL_SELP(26U), + .pllndec = SYSCON_PLL0NDEC_NDIV(4U), + .pllpdec = SYSCON_PLL0PDEC_PDIV(2U), + .pllsscg = {0x0U,(SYSCON_PLL0SSCG1_MDIV_EXT(100U) | SYSCON_PLL0SSCG1_SEL_EXT_MASK)}, + .pllRate = 100000000U, + .flags = PLL_SETUPFLAG_WAITLOCK + }; + CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */ + + /*< Set SystemCoreClock variable. */ + SystemCoreClock = 100000000U; } void board_init(void) { // Enable IOCON clock CLOCK_EnableClock(kCLOCK_Iocon); - // Init 96 MHz clock - BootClockFROHF96M(); + // Init 100 MHz clock + BOARD_BootClockPLL100M(); // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); -- cgit v1.3.1 From 98e85a296deb89dbcc05033bda26e3c9581d535b Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Apr 2024 17:09:05 +0200 Subject: bulk_in: copy buffer to ensure alignment correctness. --- src/class/usbtmc/usbtmc_device.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 4092c37ea..81e969732 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -552,9 +552,10 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint case STATE_TX_INITIATED: if(usbtmc_state.transfer_size_remaining >= sizeof(usbtmc_state.ep_bulk_in_buf)) { - // FIXME! This removes const below! + // Copy buffer to ensure alignment correctness + memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, sizeof(usbtmc_state.ep_bulk_in_buf)); TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, - (void*)(uintptr_t) usbtmc_state.devInBuffer, sizeof(usbtmc_state.ep_bulk_in_buf))); + usbtmc_state.ep_bulk_in_buf, sizeof(usbtmc_state.ep_bulk_in_buf))); usbtmc_state.devInBuffer += sizeof(usbtmc_state.ep_bulk_in_buf); usbtmc_state.transfer_size_remaining -= sizeof(usbtmc_state.ep_bulk_in_buf); usbtmc_state.transfer_size_sent += sizeof(usbtmc_state.ep_bulk_in_buf); -- cgit v1.3.1 From fdb431b5c70ff605eebda8988e1728e7118b4ab4 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Apr 2024 17:12:00 +0200 Subject: Buffer int msg to ensure alignment and placement correctness. --- src/class/usbtmc/usbtmc_device.c | 18 +++++++++++++----- src/class/usbtmc/usbtmc_device.h | 17 ++++++----------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 81e969732..59d9b184e 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -86,6 +86,11 @@ tu_static char logMsg[150]; // imposes a minimum buffer size of 32 bytes. #define USBTMCD_BUFFER_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +// Interrupt endpoint buffer size, default to 2 bytes as USB488 specification. +#ifndef CFG_TUD_USBTMC_INT_EP_SIZE +#define CFG_TUD_USBTMC_INT_EP_SIZE 2 +#endif + /* * The state machine does not allow simultaneous reading and writing. This is * consistent with USBTMC. @@ -124,13 +129,15 @@ typedef struct uint8_t ep_bulk_in; uint8_t ep_bulk_out; uint8_t ep_int_in; + uint32_t ep_bulk_in_wMaxPacketSize; + uint32_t ep_bulk_out_wMaxPacketSize; // IN buffer is only used for first packet, not the remainder // in order to deal with prepending header CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_in_buf[USBTMCD_BUFFER_SIZE]; - uint32_t ep_bulk_in_wMaxPacketSize; // OUT buffer receives one packet at a time CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_out_buf[USBTMCD_BUFFER_SIZE]; - uint32_t ep_bulk_out_wMaxPacketSize; + // Buffer int msg to ensure alignment and placement correctness + CFG_TUSB_MEM_ALIGN uint8_t ep_int_in_buf[CFG_TUD_USBTMC_INT_EP_SIZE]; uint32_t transfer_size_remaining; // also used for requested length for bulk IN. uint32_t transfer_size_sent; // To keep track of data bytes that have been queued in FIFO (not header bytes) @@ -243,12 +250,13 @@ bool tud_usbtmc_transmit_dev_msg_data( bool tud_usbtmc_transmit_notification_data(const void * data, size_t len) { #ifndef NDEBUG - TU_ASSERT(len >= 1); + TU_ASSERT(len > 0); TU_ASSERT(usbtmc_state.ep_int_in != 0); #endif - if (usbd_edpt_busy(usbtmc_state.rhport, usbtmc_state.ep_int_in)) return false; + TU_VERIFY(usbd_edpt_busy(usbtmc_state.rhport, usbtmc_state.ep_int_in)); - TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, (void *)(uintptr_t) data, len)); + TU_VERIFY(tu_memcpy_s(usbtmc_state.ep_int_in_buf, sizeof(usbtmc_state.ep_int_in_buf), data, len) == 0); + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, usbtmc_state.ep_int_in_buf, len)); return true; } diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 2f3c91dbd..af7ea6ec9 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -86,21 +86,16 @@ TU_ATTR_WEAK bool tud_usbtmc_msg_trigger_cb(usbtmc_msg_generic_t* msg); //TU_ATTR_WEAK bool tud_usbtmc_app_go_to_local_cb(); #endif -/******************************************* - * Called from app - * - * We keep a reference to the buffer, so it MUST not change until the app is - * notified that the transfer is complete. - ******************************************/ - +// Called from app +// +// We keep a reference to the buffer, so it MUST not change until the app is +// notified that the transfer is complete. bool tud_usbtmc_transmit_dev_msg_data( const void * data, size_t len, bool endOfMessage, bool usingTermChar); -// Buffers a notification to be sent to the host. The buffer must be -// valid until the tud_usbtmc_notification_complete_cb callback. The -// data starts with the bNotify1 field, see the USBTMC Specification, -// Table 13. +// Buffers a notification to be sent to the host. The data starts +// with the bNotify1 field, see the USBTMC Specification, Table 13. // // If the previous notification data has not yet been sent, this // returns false. -- cgit v1.3.1 From a018b229ba01d146f089e679524dfa72b92ec95a Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Apr 2024 17:12:23 +0200 Subject: Update .gitignore. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index e6ccec736..56ae7600f 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ hw/mcu/st/cmsis_device_f4 hw/mcu/st/cmsis_device_f7 hw/mcu/st/cmsis_device_g0 hw/mcu/st/cmsis_device_g4 +hw/mcu/st/cmsis_device_h5 hw/mcu/st/cmsis_device_h7 hw/mcu/st/cmsis_device_l0 hw/mcu/st/cmsis_device_l1 @@ -72,6 +73,7 @@ hw/mcu/st/stm32f4xx_hal_driver hw/mcu/st/stm32f7xx_hal_driver hw/mcu/st/stm32g0xx_hal_driver hw/mcu/st/stm32g4xx_hal_driver +hw/mcu/st/stm32h5xx_hal_driver hw/mcu/st/stm32h7xx_hal_driver hw/mcu/st/stm32l0xx_hal_driver hw/mcu/st/stm32l1xx_hal_driver -- cgit v1.3.1 From bd033a2d531d09478ddd947121e12aa6ece86d56 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Apr 2024 17:24:19 +0200 Subject: Fix CI. --- src/class/usbtmc/usbtmc_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 59d9b184e..f80abdaf3 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -256,7 +256,7 @@ bool tud_usbtmc_transmit_notification_data(const void * data, size_t len) TU_VERIFY(usbd_edpt_busy(usbtmc_state.rhport, usbtmc_state.ep_int_in)); TU_VERIFY(tu_memcpy_s(usbtmc_state.ep_int_in_buf, sizeof(usbtmc_state.ep_int_in_buf), data, len) == 0); - TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, usbtmc_state.ep_int_in_buf, len)); + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, usbtmc_state.ep_int_in_buf, (uint16_t)len)); return true; } -- cgit v1.3.1 From c917d47e71d9cef3f6cf096cf9606913ef7020fd Mon Sep 17 00:00:00 2001 From: Kasper Nyhus Kaae Date: Mon, 7 Mar 2022 21:30:33 +0100 Subject: audio_test_freertos & audio_4_channel_mic_freertos --- .../audio_4_channel_mic_freertos/CMakeLists.txt | 22 + .../device/audio_4_channel_mic_freertos/Makefile | 37 ++ .../device/audio_4_channel_mic_freertos/README.md | 18 + .../device/audio_4_channel_mic_freertos/skip.txt | 3 + .../src/CMakeLists.txt | 27 ++ .../src/FreeRTOSConfig/FreeRTOSConfig.h | 191 ++++++++ .../device/audio_4_channel_mic_freertos/src/main.c | 488 +++++++++++++++++++++ .../src/plot_audio_samples.py | 34 ++ .../audio_4_channel_mic_freertos/src/tusb_config.h | 128 ++++++ .../src/usb_descriptors.c | 165 +++++++ examples/device/audio_test_freertos/CMakeLists.txt | 22 + examples/device/audio_test_freertos/Makefile | 38 ++ examples/device/audio_test_freertos/README.md | 18 + examples/device/audio_test_freertos/skip.txt | 3 + .../device/audio_test_freertos/src/CMakeLists.txt | 27 ++ .../src/FreeRTOSConfig/FreeRTOSConfig.h | 191 ++++++++ examples/device/audio_test_freertos/src/main.c | 486 ++++++++++++++++++++ .../audio_test_freertos/src/plot_audio_samples.py | 34 ++ .../device/audio_test_freertos/src/tusb_config.h | 121 +++++ .../audio_test_freertos/src/usb_descriptors.c | 165 +++++++ 20 files changed, 2218 insertions(+) create mode 100644 examples/device/audio_4_channel_mic_freertos/CMakeLists.txt create mode 100644 examples/device/audio_4_channel_mic_freertos/Makefile create mode 100644 examples/device/audio_4_channel_mic_freertos/README.md create mode 100644 examples/device/audio_4_channel_mic_freertos/skip.txt create mode 100644 examples/device/audio_4_channel_mic_freertos/src/CMakeLists.txt create mode 100644 examples/device/audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 examples/device/audio_4_channel_mic_freertos/src/main.c create mode 100644 examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py create mode 100644 examples/device/audio_4_channel_mic_freertos/src/tusb_config.h create mode 100644 examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c create mode 100644 examples/device/audio_test_freertos/CMakeLists.txt create mode 100644 examples/device/audio_test_freertos/Makefile create mode 100644 examples/device/audio_test_freertos/README.md create mode 100644 examples/device/audio_test_freertos/skip.txt create mode 100644 examples/device/audio_test_freertos/src/CMakeLists.txt create mode 100644 examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 examples/device/audio_test_freertos/src/main.c create mode 100644 examples/device/audio_test_freertos/src/plot_audio_samples.py create mode 100644 examples/device/audio_test_freertos/src/tusb_config.h create mode 100644 examples/device/audio_test_freertos/src/usb_descriptors.c diff --git a/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt b/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt new file mode 100644 index 000000000..639dde99a --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.5) + +# TOP is absolute path to root directory of TinyUSB git repo +# needed for esp32sx build. TOOD could be removed later on +set(TOP "../../..") +get_filename_component(TOP "${TOP}" REALPATH) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) + +# gets PROJECT name for the example (e.g. -) +family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) + +project(${PROJECT}) + +# Checks this example is valid for the family and initializes the project +family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) + +# Check for -DFAMILY= +if(FAMILY MATCHES "^esp32s[2-3]") +else() + message(FATAL_ERROR "Invalid FAMILY specified: ${FAMILY}") +endif() diff --git a/examples/device/audio_4_channel_mic_freertos/Makefile b/examples/device/audio_4_channel_mic_freertos/Makefile new file mode 100644 index 000000000..6c8c43ddd --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/Makefile @@ -0,0 +1,37 @@ +DEPS_SUBMODULES += lib/FreeRTOS-Kernel + +include ../../../tools/top.mk +include ../../make.mk + +FREERTOS_SRC = lib/FreeRTOS-Kernel + +INC += \ + src \ + src/FreeRTOSConfig \ + $(TOP)/hw \ + $(TOP)/$(FREERTOS_SRC)/include \ + $(TOP)/$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT) + +# Example source +EXAMPLE_SOURCE = \ + src/freertos_hook.c \ + src/main.c \ + src/usb_descriptors.c + +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +# FreeRTOS source, all files in port folder +SRC_C += \ + $(FREERTOS_SRC)/list.c \ + $(FREERTOS_SRC)/queue.c \ + $(FREERTOS_SRC)/tasks.c \ + $(FREERTOS_SRC)/timers.c \ + $(subst ../../../,,$(wildcard ../../../$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT)/*.c)) + +# Suppress FreeRTOS warnings +CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls + +# FreeRTOS (lto + Os) linker issue +LDFLAGS += -Wl,--undefined=vTaskSwitchContext + +include ../../rules.mk diff --git a/examples/device/audio_4_channel_mic_freertos/README.md b/examples/device/audio_4_channel_mic_freertos/README.md new file mode 100644 index 000000000..a35c16195 --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/README.md @@ -0,0 +1,18 @@ +# How to build example for Esp32s3 +1. Load idf environment variables (eg. using the esp-idf alias `get_idf` if configured) + +2. cd into examples directory +``` +$ cd /tinyusb/examples/device/audio_4_channel_mic_freertos +``` + +3. Run make in project directory specifying the board +``` +$ make BOARD=espressif_s3_devkitc all +``` + +4. Flash the binary onto the esp32-s3 by copy-paste of the full command output by the esp-idf build system replacing **(PORT)** with eg. /dev/ttyUSB0 + +eg. + +> /home/kaspernyhus/.espressif/python_env/idf4.4_py3.8_env/bin/python ../../../../esp-idf/components/esptool_py/esptool/esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset --chip esp32s3 write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x0 _build/espressif_s3_devkitc/bootloader/bootloader.bin 0x8000 _build/espressif_s3_devkitc/partition_table/partition-table.bin 0x10000 _build/espressif_s3_devkitc/audio_4_channel_mic_freertos.bin diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt new file mode 100644 index 000000000..ae9b57f1f --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -0,0 +1,3 @@ +mcu:SAMD11 +mcu:SAME5X +mcu:SAMG \ No newline at end of file diff --git a/examples/device/audio_4_channel_mic_freertos/src/CMakeLists.txt b/examples/device/audio_4_channel_mic_freertos/src/CMakeLists.txt new file mode 100644 index 000000000..29e46d979 --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/src/CMakeLists.txt @@ -0,0 +1,27 @@ +idf_component_register(SRCS "main.c" "usb_descriptors.c" + INCLUDE_DIRS "." + REQUIRES freertos soc) + +file(TO_NATIVE_PATH "${TOP}/hw/bsp/${FAMILY}/boards/${BOARD}/board.cmake" board_cmake) + +if(EXISTS ${board_cmake}) + include(${board_cmake}) +endif() + +target_include_directories(${COMPONENT_TARGET} PUBLIC + "${TOP}/hw" + "${TOP}/src" +) + +target_compile_definitions(${COMPONENT_TARGET} PUBLIC + ESP_PLATFORM +) + +target_sources(${COMPONENT_TARGET} PUBLIC + "${TOP}/src/tusb.c" + "${TOP}/src/common/tusb_fifo.c" + "${TOP}/src/device/usbd.c" + "${TOP}/src/device/usbd_control.c" + "${TOP}/src/class/audio/audio_device.c" + "${TOP}/src/portable/espressif/esp32sx/dcd_esp32sx.c" +) \ No newline at end of file diff --git a/examples/device/audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/device/audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..ccb620720 --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,191 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// Include MCU header +#include "bsp/board_mcu.h" + +#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 + #error "ESP32-Sx should use IDF's FreeRTOSConfig.h" +#endif + +// TODO fix later +#if CFG_TUSB_MCU == OPT_MCU_MM32F327X + extern u32 SystemCoreClock; +#else + extern uint32_t SystemCoreClock; +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( 0*1024 ) // dynamic is not used +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 2 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 0 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* Define to trap errors during development. */ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) + #define configASSERT(_exp) \ + do {\ + if ( !(_exp) ) { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ + taskDISABLE_INTERRUPTS(); \ + __asm("BKPT #0\n"); \ + }\ + }\ + } while(0) +#else + #define configASSERT( x ) +#endif + +#ifdef __RX__ +/* Renesas RX series */ +#define vSoftwareInterruptISR INT_Excep_ICU_SWINT +#define vTickISR INT_Excep_CMT0_CMI0 +#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) +#define configKERNEL_INTERRUPT_PRIORITY 1 +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 + +#else + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ +#if defined(__NVIC_PRIO_BITS) + // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h + #define configPRIO_BITS __NVIC_PRIO_BITS +#elif defined(__ECLIC_INTCTLBITS) + // RISC-V Bumblebee core from nuclei + #define configPRIO_BITS __ECLIC_INTCTLBITS +#else + #error "FreeRTOS configPRIO_BITS to be defined" +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< +#include +#include + +#include "bsp/board.h" +#include "tusb.h" + +// ESP-IDF need "freertos/" prefix in include path. +// CFG_TUSB_OS_INC_PATH should be defined accordingly. +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "freertos/timers.h" + +#define USBD_STACK_SIZE 4096 + + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ + +#ifndef AUDIO_SAMPLE_RATE +#define AUDIO_SAMPLE_RATE 48000 +#endif + +/* Blink pattern + * - 250 ms : device not mounted + * - 1000 ms : device mounted + * - 2500 ms : device is suspended + */ +enum { + BLINK_NOT_MOUNTED = 250, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, +}; + +// static timer +StaticTimer_t blinky_tmdef; +TimerHandle_t blinky_tm; +StackType_t usb_device_stack[USBD_STACK_SIZE]; +StaticTask_t usb_device_taskdef; + + +// Audio controls +// Current states +bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0 +uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0 +uint32_t sampFreq; +uint8_t clkValid; + +// Range states +audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; // Volume range state +audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state + +// Audio test data +uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_EP_SZ_IN/2]; // Ensure half word aligned +uint16_t samples[] = {0, 0, 0, 0}; + +void led_blinky_cb(TimerHandle_t xTimer); +void usb_device_task(void* param); +void audio_task(void); + +/*------------- MAIN -------------*/ +int main(void) +{ + board_init(); + + // soft timer for blinky + blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef); + xTimerStart(blinky_tm, 0); + + // Init values + sampFreq = AUDIO_SAMPLE_RATE; + clkValid = 1; + + sampleFreqRng.wNumSubRanges = 1; + sampleFreqRng.subrange[0].bMin = AUDIO_SAMPLE_RATE; + sampleFreqRng.subrange[0].bMax = AUDIO_SAMPLE_RATE; + sampleFreqRng.subrange[0].bRes = 0; + + // Create a task for tinyusb device stack + (void) xTaskCreateStatic( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); + + // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 + #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + vTaskStartScheduler(); + #endif + + return 0; +} + +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +void app_main(void) +{ + main(); +} +#endif + +// USB Device Driver task +// This top level thread process all usb events and invoke callbacks +void usb_device_task(void* param) +{ + (void) param; + + // This should be called after scheduler/kernel is started. + // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. + tusb_init(); + + // RTOS forever loop + while (1) + { + // tinyusb device task + tud_task(); + } +} + +//--------------------------------------------------------------------+ +// Device callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +void tud_mount_cb(void) +{ + xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); +} + +// Invoked when device is unmounted +void tud_umount_cb(void) +{ + xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); +} + +// Invoked when usb bus is suspended +// remote_wakeup_en : if host allow us to perform remote wakeup +// Within 7ms, device must draw an average of current less than 2.5 mA from bus +void tud_suspend_cb(bool remote_wakeup_en) +{ + (void) remote_wakeup_en; + xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_SUSPENDED), 0); +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) +{ + xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); +} + +//--------------------------------------------------------------------+ +// AUDIO Task +//--------------------------------------------------------------------+ + +void audio_task(void) +{ + // Yet to be filled - e.g. put meas data into TX FIFOs etc. + // asm("nop"); +} + +//--------------------------------------------------------------------+ +// Application Callback API Implementations +//--------------------------------------------------------------------+ + +// Invoked when audio class specific set request received for an EP +bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) +{ + (void) rhport; + (void) pBuff; + + // We do not support any set range requests here, only current value requests + TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t ep = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) ep; + + return false; // Yet not implemented +} + +// Invoked when audio class specific set request received for an interface +bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) +{ + (void) rhport; + (void) pBuff; + + // We do not support any set range requests here, only current value requests + TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t itf = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) itf; + + return false; // Yet not implemented +} + +// Invoked when audio class specific set request received for an entity +bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t itf = TU_U16_LOW(p_request->wIndex); + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + (void) itf; + + // We do not support any set range requests here, only current value requests + TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + + // If request is for our feature unit + if ( entityID == 2 ) + { + switch ( ctrlSel ) + { + case AUDIO_FU_CTRL_MUTE: + // Request uses format layout 1 + TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t)); + + mute[channelNum] = ((audio_control_cur_1_t*) pBuff)->bCur; + + TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); + return true; + + case AUDIO_FU_CTRL_VOLUME: + // Request uses format layout 2 + TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t)); + + volume[channelNum] = ((audio_control_cur_2_t*) pBuff)->bCur; + + TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); + return true; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + return false; // Yet not implemented +} + +// Invoked when audio class specific get request received for an EP +bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t ep = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) ep; + + // return tud_control_xfer(rhport, p_request, &tmp, 1); + + return false; // Yet not implemented +} + +// Invoked when audio class specific get request received for an interface +bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t itf = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) itf; + + return false; // Yet not implemented +} + +// Invoked when audio class specific get request received for an entity +bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + // uint8_t itf = TU_U16_LOW(p_request->wIndex); // Since we have only one audio function implemented, we do not need the itf value + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + // Input terminal (Microphone input) + if (entityID == 1) + { + switch ( ctrlSel ) + { + case AUDIO_TE_CTRL_CONNECTOR: + { + // The terminal connector control only has a get request with only the CUR attribute. + audio_desc_channel_cluster_t ret; + + // Those are dummy values for now + ret.bNrChannels = 1; + ret.bmChannelConfig = 0; + ret.iChannelNames = 0; + + TU_LOG2(" Get terminal connector\r\n"); + + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret)); + } + break; + + // Unknown/Unsupported control selector + default: + TU_BREAKPOINT(); + return false; + } + } + + // Feature unit + if (entityID == 2) + { + switch ( ctrlSel ) + { + case AUDIO_FU_CTRL_MUTE: + // Audio control mute cur parameter block consists of only one byte - we thus can send it right away + // There does not exist a range parameter block for mute + TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); + return tud_control_xfer(rhport, p_request, &mute[channelNum], 1); + + case AUDIO_FU_CTRL_VOLUME: + switch ( p_request->bRequest ) + { + case AUDIO_CS_REQ_CUR: + TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); + return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum])); + + case AUDIO_CS_REQ_RANGE: + TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum); + + // Copy values - only for testing - better is version below + audio_control_range_2_n_t(1) + ret; + + ret.wNumSubRanges = 1; + ret.subrange[0].bMin = -90; // -90 dB + ret.subrange[0].bMax = 90; // +90 dB + ret.subrange[0].bRes = 1; // 1 dB steps + + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret)); + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + break; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + + // Clock Source unit + if ( entityID == 4 ) + { + switch ( ctrlSel ) + { + case AUDIO_CS_CTRL_SAM_FREQ: + // channelNum is always zero in this case + switch ( p_request->bRequest ) + { + case AUDIO_CS_REQ_CUR: + TU_LOG2(" Get Sample Freq.\r\n"); + return tud_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); + + case AUDIO_CS_REQ_RANGE: + TU_LOG2(" Get Sample Freq. range\r\n"); + return tud_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng)); + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + break; + + case AUDIO_CS_CTRL_CLK_VALID: + // Only cur attribute exists for this request + TU_LOG2(" Get Sample Freq. valid\r\n"); + return tud_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid)); + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + + TU_LOG2(" Unsupported entity: %d\r\n", entityID); + return false; // Yet not implemented +} + +bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting) +{ + (void) rhport; + (void) itf; + (void) ep_in; + (void) cur_alt_setting; + + tud_audio_write((uint8_t*)i2s_dummy_buffer, CFG_TUD_AUDIO_EP_SZ_IN); + + return true; +} + +bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting) +{ + (void) rhport; + (void) n_bytes_copied; + (void) itf; + (void) ep_in; + (void) cur_alt_setting; + + uint16_t* p_buff = i2s_dummy_buffer; + for (int samples_num = 0; samples_num < AUDIO_SAMPLE_RATE/1000; samples_num++) { + for (int ch=0; ch < CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX; ch++) { + *p_buff++ = samples[ch]; + samples[ch] = samples[ch]+(ch+1); + } + } + + return true; +} + +bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + (void) p_request; + + return true; +} + +///--------------------------------------------------------------------+ +// BLINKING TASK +//--------------------------------------------------------------------+ +void led_blinky_cb(TimerHandle_t xTimer) +{ + (void) xTimer; + static bool led_state = false; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle +} diff --git a/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py b/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py new file mode 100644 index 000000000..9ab15135d --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py @@ -0,0 +1,34 @@ +import sounddevice as sd +import matplotlib.pyplot as plt +import numpy as np +import platform + +if __name__ == '__main__': + + # If you got "ValueError: No input device matching", that is because your PC name example device + # differently from tested list below. Uncomment the next line to see full list and try to pick correct one + # print(sd.query_devices()) + + fs = 48000 # Sample rate + duration = 100e-3 # Duration of recording + + if platform.system() == 'Windows': + # WDM-KS is needed since there are more than one MicNode device APIs (at least in Windows) + device = 'Microphone (MicNode_4_Ch), Windows WDM-KS' + elif platform.system() == 'Darwin': + device = 'MicNode_4_Ch' + else: + device ='default' + + myrecording = sd.rec(int(duration * fs), samplerate=fs, channels=4, dtype='int16', device=device) + print('Waiting...') + sd.wait() # Wait until recording is finished + print('Done!') + + time = np.arange(0, duration, 1 / fs) # time vector + plt.plot(time, myrecording) + plt.xlabel('Time [s]') + plt.ylabel('Amplitude') + plt.title('MicNode 4 Channel') + plt.show() + \ No newline at end of file diff --git a/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h b/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h new file mode 100644 index 000000000..f13865084 --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h @@ -0,0 +1,128 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU +#error CFG_TUSB_MCU must be defined +#endif + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_DEVICE_RHPORT_NUM + #define BOARD_DEVICE_RHPORT_NUM 0 +#endif + +#ifndef BOARD_DEVICE_RHPORT_SPEED + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED +#endif + +#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE + +#ifndef CFG_TUSB_OS + #define CFG_TUSB_OS OPT_OS_FREERTOS +#endif + +// Espressif IDF requires "freertos/" prefix in include path +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + #define CFG_TUSB_OS_INC_PATH freertos/ +#endif + +#ifndef CFG_TUSB_DEBUG + #define CFG_TUSB_DEBUG 0 +#endif + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +// #define CFG_TUSB_DEBUG 0 + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//------------- CLASS -------------// +#define CFG_TUD_CDC 0 +#define CFG_TUD_MSC 0 +#define CFG_TUD_HID 0 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_AUDIO 1 +#define CFG_TUD_VENDOR 0 + +//-------------------------------------------------------------------- +// AUDIO CLASS DRIVER CONFIGURATION +//-------------------------------------------------------------------- + +// Have a look into audio_device.h for all configurations + +#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_FOUR_CH_DESC_LEN + +#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 +#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 + +#define CFG_TUD_AUDIO_ENABLE_EP_IN 1 +#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup +#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 4 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup +#define CFG_TUD_AUDIO_EP_SZ_IN 48 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX // 48 Samples (48 kHz) x 2 Bytes/Sample x CFG_TUD_AUDIO_N_CHANNELS_TX Channels - the Windows driver always needs an extra sample per channel of space more, otherwise it complains... found by trial and error +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN + +#define CFG_TUD_AUDIO_ENABLE_ENCODING 0 +#define CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING 0 +#define CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX 2 // One I2S stream contains two channels, each stream is saved within one support FIFO - this value is currently fixed, the driver does not support a changing value +#define CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX) +#define CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ (CFG_TUD_AUDIO_EP_SZ_IN / CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO) + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c b/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c new file mode 100644 index 000000000..16355a7fc --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c @@ -0,0 +1,165 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "tusb.h" + +/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. + * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. + * + * Auto ProductID layout's Bitmap: + * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] + */ +#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ + _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) ) + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +tusb_desc_device_t const desc_device = +{ + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + + // Use Interface Association Descriptor (IAD) for CDC + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = 0xCafe, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const * tud_descriptor_device_cb(void) +{ + return (uint8_t const *) &desc_device; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ +enum +{ + ITF_NUM_AUDIO_CONTROL = 0, + ITF_NUM_AUDIO_STREAMING, + ITF_NUM_TOTAL +}; + +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_FOUR_CH_DESC_LEN) + +#if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) + // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number + // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... + #define EPNUM_AUDIO 0x03 + +#elif TU_CHECK_MCU(OPT_MCU_NRF5X) + // nRF5x ISO can only be endpoint 8 + #define EPNUM_AUDIO 0x08 + +#else + #define EPNUM_AUDIO 0x01 +#endif + +uint8_t const desc_configuration[] = +{ + // Interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + + // Interface number, string index, EP Out & EP In address, EP size + TUD_AUDIO_MIC_FOUR_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) +}; + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) +{ + (void) index; // for multiple configurations + return desc_configuration; +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +// array of pointer to string descriptors +char const* string_desc_arr [] = +{ + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "PaniRCorp", // 1: Manufacturer + "MicNode_4_Ch", // 2: Product + "123458", // 3: Serials, should use chip ID + "UAC2", // 4: Audio Interface +}; + +static uint16_t _desc_str[32]; + +// Invoked when received GET STRING DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) +{ + (void) langid; + + uint8_t chr_count; + + if ( index == 0) + { + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + }else + { + // Convert ASCII string into UTF-16 + + if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + + const char* str = string_desc_arr[index]; + + // Cap at max char + chr_count = strlen(str); + if ( chr_count > 31 ) chr_count = 31; + + for(uint8_t i=0; i-) +family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) + +project(${PROJECT}) + +# Checks this example is valid for the family and initializes the project +family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) + +# Check for -DFAMILY= +if(FAMILY MATCHES "^esp32s[2-3]") +else() + message(FATAL_ERROR "Invalid FAMILY specified: ${FAMILY}") +endif() diff --git a/examples/device/audio_test_freertos/Makefile b/examples/device/audio_test_freertos/Makefile new file mode 100644 index 000000000..e5b88df5e --- /dev/null +++ b/examples/device/audio_test_freertos/Makefile @@ -0,0 +1,38 @@ +DEPS_SUBMODULES += lib/FreeRTOS-Kernel + +include ../../../tools/top.mk +include ../../make.mk + +FREERTOS_SRC = lib/FreeRTOS-Kernel + +INC += \ + src \ + src/FreeRTOSConfig \ + $(TOP)/hw \ + $(TOP)/$(FREERTOS_SRC)/include \ + $(TOP)/$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT) + +# Example source +EXAMPLE_SOURCE = \ + src/freertos_hook.c \ + src/main.c \ + src/msc_disk.c \ + src/usb_descriptors.c + +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +# FreeRTOS source, all files in port folder +SRC_C += \ + $(FREERTOS_SRC)/list.c \ + $(FREERTOS_SRC)/queue.c \ + $(FREERTOS_SRC)/tasks.c \ + $(FREERTOS_SRC)/timers.c \ + $(subst ../../../,,$(wildcard ../../../$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT)/*.c)) + +# Suppress FreeRTOS warnings +CFLAGS += -Wno-error=cast-qual + +# FreeRTOS (lto + Os) linker issue +LDFLAGS += -Wl,--undefined=vTaskSwitchContext + +include ../../rules.mk \ No newline at end of file diff --git a/examples/device/audio_test_freertos/README.md b/examples/device/audio_test_freertos/README.md new file mode 100644 index 000000000..077a2a1b6 --- /dev/null +++ b/examples/device/audio_test_freertos/README.md @@ -0,0 +1,18 @@ +# How to build example for Esp32s3 +1. Load idf environment variables (eg. using the esp-idf alias `get_idf` if configured) + +2. cd into examples directory +``` +$ cd /tinyusb/examples/device/audio_test_freertos +``` + +3. Run make in project directory specifying the board +``` +$ make BOARD=espressif_s3_devkitc all +``` + +4. Flash the binary onto the esp32-s3 by copy-paste of the full command output by the esp-idf build system replacing **(PORT)** with eg. /dev/ttyUSB0 + +eg. + +> /home/kaspernyhus/.espressif/python_env/idf4.4_py3.8_env/bin/python ../../../../esp-idf/components/esptool_py/esptool/esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset --chip esp32s3 write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x0 _build/espressif_s3_devkitc/bootloader/bootloader.bin 0x8000 _build/espressif_s3_devkitc/partition_table/partition-table.bin 0x10000 _build/espressif_s3_devkitc/audio_test_freertos.bin \ No newline at end of file diff --git a/examples/device/audio_test_freertos/skip.txt b/examples/device/audio_test_freertos/skip.txt new file mode 100644 index 000000000..ae9b57f1f --- /dev/null +++ b/examples/device/audio_test_freertos/skip.txt @@ -0,0 +1,3 @@ +mcu:SAMD11 +mcu:SAME5X +mcu:SAMG \ No newline at end of file diff --git a/examples/device/audio_test_freertos/src/CMakeLists.txt b/examples/device/audio_test_freertos/src/CMakeLists.txt new file mode 100644 index 000000000..29e46d979 --- /dev/null +++ b/examples/device/audio_test_freertos/src/CMakeLists.txt @@ -0,0 +1,27 @@ +idf_component_register(SRCS "main.c" "usb_descriptors.c" + INCLUDE_DIRS "." + REQUIRES freertos soc) + +file(TO_NATIVE_PATH "${TOP}/hw/bsp/${FAMILY}/boards/${BOARD}/board.cmake" board_cmake) + +if(EXISTS ${board_cmake}) + include(${board_cmake}) +endif() + +target_include_directories(${COMPONENT_TARGET} PUBLIC + "${TOP}/hw" + "${TOP}/src" +) + +target_compile_definitions(${COMPONENT_TARGET} PUBLIC + ESP_PLATFORM +) + +target_sources(${COMPONENT_TARGET} PUBLIC + "${TOP}/src/tusb.c" + "${TOP}/src/common/tusb_fifo.c" + "${TOP}/src/device/usbd.c" + "${TOP}/src/device/usbd_control.c" + "${TOP}/src/class/audio/audio_device.c" + "${TOP}/src/portable/espressif/esp32sx/dcd_esp32sx.c" +) \ No newline at end of file diff --git a/examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..ccb620720 --- /dev/null +++ b/examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,191 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// Include MCU header +#include "bsp/board_mcu.h" + +#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 + #error "ESP32-Sx should use IDF's FreeRTOSConfig.h" +#endif + +// TODO fix later +#if CFG_TUSB_MCU == OPT_MCU_MM32F327X + extern u32 SystemCoreClock; +#else + extern uint32_t SystemCoreClock; +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( 0*1024 ) // dynamic is not used +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 2 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 0 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* Define to trap errors during development. */ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) + #define configASSERT(_exp) \ + do {\ + if ( !(_exp) ) { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ + taskDISABLE_INTERRUPTS(); \ + __asm("BKPT #0\n"); \ + }\ + }\ + } while(0) +#else + #define configASSERT( x ) +#endif + +#ifdef __RX__ +/* Renesas RX series */ +#define vSoftwareInterruptISR INT_Excep_ICU_SWINT +#define vTickISR INT_Excep_CMT0_CMI0 +#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) +#define configKERNEL_INTERRUPT_PRIORITY 1 +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 + +#else + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ +#if defined(__NVIC_PRIO_BITS) + // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h + #define configPRIO_BITS __NVIC_PRIO_BITS +#elif defined(__ECLIC_INTCTLBITS) + // RISC-V Bumblebee core from nuclei + #define configPRIO_BITS __ECLIC_INTCTLBITS +#else + #error "FreeRTOS configPRIO_BITS to be defined" +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< +#include +#include + +#include "bsp/board.h" +#include "tusb.h" + +// ESP-IDF need "freertos/" prefix in include path. +// CFG_TUSB_OS_INC_PATH should be defined accordingly. +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "freertos/timers.h" + +#define USBD_STACK_SIZE 4096 + + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ + +#ifndef AUDIO_SAMPLE_RATE +#define AUDIO_SAMPLE_RATE 48000 +#endif + +/* Blink pattern + * - 250 ms : device not mounted + * - 1000 ms : device mounted + * - 2500 ms : device is suspended + */ +enum { + BLINK_NOT_MOUNTED = 250, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, +}; + +// static timer +StaticTimer_t blinky_tmdef; +TimerHandle_t blinky_tm; +StackType_t usb_device_stack[USBD_STACK_SIZE]; +StaticTask_t usb_device_taskdef; + + +// Audio controls +// Current states +bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0 +uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0 +uint32_t sampFreq; +uint8_t clkValid; + +// Range states +audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; // Volume range state +audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state + +// Audio test data +uint16_t test_buffer_audio[CFG_TUD_AUDIO_EP_SZ_IN/2]; +uint16_t startVal = 0; + +void led_blinky_cb(TimerHandle_t xTimer); +void usb_device_task(void* param); +void audio_task(void); + +/*------------- MAIN -------------*/ +int main(void) +{ + board_init(); + + // soft timer for blinky + blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef); + xTimerStart(blinky_tm, 0); + + // Init values + sampFreq = AUDIO_SAMPLE_RATE; + clkValid = 1; + + sampleFreqRng.wNumSubRanges = 1; + sampleFreqRng.subrange[0].bMin = AUDIO_SAMPLE_RATE; + sampleFreqRng.subrange[0].bMax = AUDIO_SAMPLE_RATE; + sampleFreqRng.subrange[0].bRes = 0; + + // Create a task for tinyusb device stack + (void) xTaskCreateStatic( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); + + // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 + #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + vTaskStartScheduler(); + #endif + + return 0; +} + +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +void app_main(void) +{ + main(); +} +#endif + +// USB Device Driver task +// This top level thread process all usb events and invoke callbacks +void usb_device_task(void* param) +{ + (void) param; + + // This should be called after scheduler/kernel is started. + // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. + tusb_init(); + + // RTOS forever loop + while (1) + { + // tinyusb device task + tud_task(); + } +} + +//--------------------------------------------------------------------+ +// Device callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +void tud_mount_cb(void) +{ + xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); +} + +// Invoked when device is unmounted +void tud_umount_cb(void) +{ + xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); +} + +// Invoked when usb bus is suspended +// remote_wakeup_en : if host allow us to perform remote wakeup +// Within 7ms, device must draw an average of current less than 2.5 mA from bus +void tud_suspend_cb(bool remote_wakeup_en) +{ + (void) remote_wakeup_en; + xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_SUSPENDED), 0); +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) +{ + xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); +} + +//--------------------------------------------------------------------+ +// AUDIO Task +//--------------------------------------------------------------------+ + +void audio_task(void) +{ + // Yet to be filled - e.g. put meas data into TX FIFOs etc. + // asm("nop"); +} + +//--------------------------------------------------------------------+ +// Application Callback API Implementations +//--------------------------------------------------------------------+ + +// Invoked when audio class specific set request received for an EP +bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) +{ + (void) rhport; + (void) pBuff; + + // We do not support any set range requests here, only current value requests + TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t ep = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) ep; + + return false; // Yet not implemented +} + +// Invoked when audio class specific set request received for an interface +bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) +{ + (void) rhport; + (void) pBuff; + + // We do not support any set range requests here, only current value requests + TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t itf = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) itf; + + return false; // Yet not implemented +} + +// Invoked when audio class specific set request received for an entity +bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t itf = TU_U16_LOW(p_request->wIndex); + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + (void) itf; + + // We do not support any set range requests here, only current value requests + TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + + // If request is for our feature unit + if ( entityID == 2 ) + { + switch ( ctrlSel ) + { + case AUDIO_FU_CTRL_MUTE: + // Request uses format layout 1 + TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t)); + + mute[channelNum] = ((audio_control_cur_1_t*) pBuff)->bCur; + + TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); + return true; + + case AUDIO_FU_CTRL_VOLUME: + // Request uses format layout 2 + TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t)); + + volume[channelNum] = ((audio_control_cur_2_t*) pBuff)->bCur; + + TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); + return true; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + return false; // Yet not implemented +} + +// Invoked when audio class specific get request received for an EP +bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t ep = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) ep; + + // return tud_control_xfer(rhport, p_request, &tmp, 1); + + return false; // Yet not implemented +} + +// Invoked when audio class specific get request received for an interface +bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t itf = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) itf; + + return false; // Yet not implemented +} + +// Invoked when audio class specific get request received for an entity +bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + // uint8_t itf = TU_U16_LOW(p_request->wIndex); // Since we have only one audio function implemented, we do not need the itf value + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + // Input terminal (Microphone input) + if (entityID == 1) + { + switch ( ctrlSel ) + { + case AUDIO_TE_CTRL_CONNECTOR: + { + // The terminal connector control only has a get request with only the CUR attribute. + audio_desc_channel_cluster_t ret; + + // Those are dummy values for now + ret.bNrChannels = 1; + ret.bmChannelConfig = 0; + ret.iChannelNames = 0; + + TU_LOG2(" Get terminal connector\r\n"); + + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret)); + } + break; + + // Unknown/Unsupported control selector + default: + TU_BREAKPOINT(); + return false; + } + } + + // Feature unit + if (entityID == 2) + { + switch ( ctrlSel ) + { + case AUDIO_FU_CTRL_MUTE: + // Audio control mute cur parameter block consists of only one byte - we thus can send it right away + // There does not exist a range parameter block for mute + TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); + return tud_control_xfer(rhport, p_request, &mute[channelNum], 1); + + case AUDIO_FU_CTRL_VOLUME: + switch ( p_request->bRequest ) + { + case AUDIO_CS_REQ_CUR: + TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); + return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum])); + + case AUDIO_CS_REQ_RANGE: + TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum); + + // Copy values - only for testing - better is version below + audio_control_range_2_n_t(1) + ret; + + ret.wNumSubRanges = 1; + ret.subrange[0].bMin = -90; // -90 dB + ret.subrange[0].bMax = 90; // +90 dB + ret.subrange[0].bRes = 1; // 1 dB steps + + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret)); + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + break; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + + // Clock Source unit + if ( entityID == 4 ) + { + switch ( ctrlSel ) + { + case AUDIO_CS_CTRL_SAM_FREQ: + // channelNum is always zero in this case + switch ( p_request->bRequest ) + { + case AUDIO_CS_REQ_CUR: + TU_LOG2(" Get Sample Freq.\r\n"); + return tud_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); + + case AUDIO_CS_REQ_RANGE: + TU_LOG2(" Get Sample Freq. range\r\n"); + return tud_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng)); + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + break; + + case AUDIO_CS_CTRL_CLK_VALID: + // Only cur attribute exists for this request + TU_LOG2(" Get Sample Freq. valid\r\n"); + return tud_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid)); + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + + TU_LOG2(" Unsupported entity: %d\r\n", entityID); + return false; // Yet not implemented +} + +bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting) +{ + (void) rhport; + (void) itf; + (void) ep_in; + (void) cur_alt_setting; + + tud_audio_write ((uint8_t *)test_buffer_audio, CFG_TUD_AUDIO_EP_SZ_IN); + + return true; +} + +bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting) +{ + (void) rhport; + (void) n_bytes_copied; + (void) itf; + (void) ep_in; + (void) cur_alt_setting; + + for (size_t cnt = 0; cnt < CFG_TUD_AUDIO_EP_SZ_IN/2; cnt++) + { + test_buffer_audio[cnt] = startVal++; + } + + return true; +} + +bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + (void) p_request; + startVal = 0; + + return true; +} + +///--------------------------------------------------------------------+ +// BLINKING TASK +//--------------------------------------------------------------------+ +void led_blinky_cb(TimerHandle_t xTimer) +{ + (void) xTimer; + static bool led_state = false; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle +} diff --git a/examples/device/audio_test_freertos/src/plot_audio_samples.py b/examples/device/audio_test_freertos/src/plot_audio_samples.py new file mode 100644 index 000000000..6e3c4978e --- /dev/null +++ b/examples/device/audio_test_freertos/src/plot_audio_samples.py @@ -0,0 +1,34 @@ +import sounddevice as sd +import matplotlib.pyplot as plt +import numpy as np +import platform + +if __name__ == '__main__': + + # If you got "ValueError: No input device matching", that is because your PC name example device + # differently from tested list below. Uncomment the next line to see full list and try to pick correct one + # print(sd.query_devices()) + + fs = 48000 # Sample rate + duration = 100e-3 # Duration of recording + + if platform.system() == 'Windows': + # MME is needed since there are more than one MicNode device APIs (at least in Windows) + device = 'Microphone (MicNode) MME' + elif platform.system() == 'Darwin': + device = 'MicNode' + else: + device ='default' + + myrecording = sd.rec(int(duration * fs), samplerate=fs, channels=1, dtype='int16', device=device) + print('Waiting...') + sd.wait() # Wait until recording is finished + print('Done!') + + time = np.arange(0, duration, 1 / fs) # time vector + plt.plot(time, myrecording) + plt.xlabel('Time [s]') + plt.ylabel('Amplitude') + plt.title('MicNode') + plt.show() + \ No newline at end of file diff --git a/examples/device/audio_test_freertos/src/tusb_config.h b/examples/device/audio_test_freertos/src/tusb_config.h new file mode 100644 index 000000000..598706e78 --- /dev/null +++ b/examples/device/audio_test_freertos/src/tusb_config.h @@ -0,0 +1,121 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU + #error CFG_TUSB_MCU must be defined +#endif + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_DEVICE_RHPORT_NUM + #define BOARD_DEVICE_RHPORT_NUM 0 +#endif + +#ifndef BOARD_DEVICE_RHPORT_SPEED + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED +#endif + +#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE + +#ifndef CFG_TUSB_OS + #define CFG_TUSB_OS OPT_OS_FREERTOS +#endif + +// Espressif IDF requires "freertos/" prefix in include path +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + #define CFG_TUSB_OS_INC_PATH freertos/ +#endif + +#ifndef CFG_TUSB_DEBUG + #define CFG_TUSB_DEBUG 0 +#endif + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +// #define CFG_TUSB_DEBUG 0 + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION + #define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN + #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//------------- CLASS -------------// +#define CFG_TUD_CDC 0 +#define CFG_TUD_MSC 0 +#define CFG_TUD_HID 0 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_AUDIO 1 +#define CFG_TUD_VENDOR 0 + +//-------------------------------------------------------------------- +// AUDIO CLASS DRIVER CONFIGURATION +//-------------------------------------------------------------------- + +// Have a look into audio_device.h for all configurations + +#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_ONE_CH_DESC_LEN +#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 // Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes) +#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 // Size of control request buffer + +#define CFG_TUD_AUDIO_ENABLE_EP_IN 1 +#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below +#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor! +#define CFG_TUD_AUDIO_EP_SZ_IN 48 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX // 48 Samples (48 kHz) x 2 Bytes/Sample x 1 Channel +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN // Maximum EP IN size for all AS alternate settings used +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN + 1 + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/audio_test_freertos/src/usb_descriptors.c b/examples/device/audio_test_freertos/src/usb_descriptors.c new file mode 100644 index 000000000..b8df75e71 --- /dev/null +++ b/examples/device/audio_test_freertos/src/usb_descriptors.c @@ -0,0 +1,165 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "tusb.h" + +/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. + * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. + * + * Auto ProductID layout's Bitmap: + * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] + */ +#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ + _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) ) + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +tusb_desc_device_t const desc_device = +{ + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + + // Use Interface Association Descriptor (IAD) for CDC + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = 0xCafe, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const * tud_descriptor_device_cb(void) +{ + return (uint8_t const *) &desc_device; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ +enum +{ + ITF_NUM_AUDIO_CONTROL = 0, + ITF_NUM_AUDIO_STREAMING, + ITF_NUM_TOTAL +}; + +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_ONE_CH_DESC_LEN) + +#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX + // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number + // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... + #define EPNUM_AUDIO 0x03 + +#elif TU_CHECK_MCU(OPT_MCU_NRF5X) + // nRF5x ISO can only be endpoint 8 + #define EPNUM_AUDIO 0x08 + +#else + #define EPNUM_AUDIO 0x01 +#endif + +uint8_t const desc_configuration[] = +{ + // Interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + + // Interface number, string index, EP Out & EP In address, EP size + TUD_AUDIO_MIC_ONE_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) +}; + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) +{ + (void) index; // for multiple configurations + return desc_configuration; +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +// array of pointer to string descriptors +char const* string_desc_arr [] = +{ + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "PaniRCorp", // 1: Manufacturer + "MicNode", // 2: Product + "123456", // 3: Serials, should use chip ID + "UAC2", // 4: Audio Interface +}; + +static uint16_t _desc_str[32]; + +// Invoked when received GET STRING DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) +{ + (void) langid; + + uint8_t chr_count; + + if ( index == 0) + { + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + }else + { + // Convert ASCII string into UTF-16 + + if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + + const char* str = string_desc_arr[index]; + + // Cap at max char + chr_count = strlen(str); + if ( chr_count > 31 ) chr_count = 31; + + for(uint8_t i=0; i Date: Sat, 27 Apr 2024 21:44:25 +0200 Subject: Update build system. --- .../audio_4_channel_mic_freertos/CMakeLists.txt | 34 ++++-- .../device/audio_4_channel_mic_freertos/Makefile | 17 +-- .../device/audio_4_channel_mic_freertos/README.md | 5 +- .../sdkconfig.defaults | 3 + .../device/audio_4_channel_mic_freertos/skip.txt | 3 +- .../src/CMakeLists.txt | 29 +----- .../src/FreeRTOSConfig/FreeRTOSConfig.h | 45 ++++---- .../src/freertos_hook.c | 115 +++++++++++++++++++++ .../device/audio_4_channel_mic_freertos/src/main.c | 46 ++++++--- .../audio_4_channel_mic_freertos/src/tusb_config.h | 45 ++++---- examples/device/audio_test_freertos/CMakeLists.txt | 34 ++++-- examples/device/audio_test_freertos/Makefile | 20 ++-- examples/device/audio_test_freertos/README.md | 5 +- .../device/audio_test_freertos/sdkconfig.defaults | 3 + .../device/audio_test_freertos/src/CMakeLists.txt | 29 +----- .../src/FreeRTOSConfig/FreeRTOSConfig.h | 45 ++++---- .../device/audio_test_freertos/src/freertos_hook.c | 115 +++++++++++++++++++++ examples/device/audio_test_freertos/src/main.c | 102 +++++++++++------- .../audio_test_freertos/src/plot_audio_samples.py | 2 +- 19 files changed, 484 insertions(+), 213 deletions(-) create mode 100644 examples/device/audio_4_channel_mic_freertos/sdkconfig.defaults create mode 100644 examples/device/audio_4_channel_mic_freertos/src/freertos_hook.c create mode 100644 examples/device/audio_test_freertos/sdkconfig.defaults create mode 100644 examples/device/audio_test_freertos/src/freertos_hook.c diff --git a/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt b/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt index 639dde99a..eb22014fb 100644 --- a/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt +++ b/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt @@ -1,22 +1,34 @@ -cmake_minimum_required(VERSION 3.5) - -# TOP is absolute path to root directory of TinyUSB git repo -# needed for esp32sx build. TOOD could be removed later on -set(TOP "../../..") -get_filename_component(TOP "${TOP}" REALPATH) +cmake_minimum_required(VERSION 3.17) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) # gets PROJECT name for the example (e.g. -) family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) -project(${PROJECT}) +project(${PROJECT} C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) -# Check for -DFAMILY= -if(FAMILY MATCHES "^esp32s[2-3]") -else() - message(FATAL_ERROR "Invalid FAMILY specified: ${FAMILY}") +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() endif() + +add_executable(${PROJECT}) + +# Example source +target_sources(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/freertos_hook.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c + ) + +# Example include +target_include_directories(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src + ) + +# Configure compilation flags and libraries for the example with FreeRTOS. +# See the corresponding function in hw/bsp/FAMILY/family.cmake for details. +family_configure_device_example(${PROJECT} freertos) diff --git a/examples/device/audio_4_channel_mic_freertos/Makefile b/examples/device/audio_4_channel_mic_freertos/Makefile index 6c8c43ddd..48a3148f8 100644 --- a/examples/device/audio_4_channel_mic_freertos/Makefile +++ b/examples/device/audio_4_channel_mic_freertos/Makefile @@ -1,23 +1,21 @@ -DEPS_SUBMODULES += lib/FreeRTOS-Kernel - -include ../../../tools/top.mk -include ../../make.mk +include ../../build_system/make/make.mk FREERTOS_SRC = lib/FreeRTOS-Kernel +FREERTOS_PORTABLE_PATH = $(FREERTOS_SRC)/portable/$(if $(findstring iar,$(TOOLCHAIN)),IAR,GCC) INC += \ src \ src/FreeRTOSConfig \ $(TOP)/hw \ $(TOP)/$(FREERTOS_SRC)/include \ - $(TOP)/$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT) + $(TOP)/$(FREERTOS_PORTABLE_SRC) \ # Example source EXAMPLE_SOURCE = \ src/freertos_hook.c \ src/main.c \ src/usb_descriptors.c - + SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) # FreeRTOS source, all files in port folder @@ -26,7 +24,10 @@ SRC_C += \ $(FREERTOS_SRC)/queue.c \ $(FREERTOS_SRC)/tasks.c \ $(FREERTOS_SRC)/timers.c \ - $(subst ../../../,,$(wildcard ../../../$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT)/*.c)) + $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.c)) + +SRC_S += \ + $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.s)) # Suppress FreeRTOS warnings CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls @@ -34,4 +35,4 @@ CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls # FreeRTOS (lto + Os) linker issue LDFLAGS += -Wl,--undefined=vTaskSwitchContext -include ../../rules.mk +include ../../build_system/make/rules.mk \ No newline at end of file diff --git a/examples/device/audio_4_channel_mic_freertos/README.md b/examples/device/audio_4_channel_mic_freertos/README.md index a35c16195..a99f28bc3 100644 --- a/examples/device/audio_4_channel_mic_freertos/README.md +++ b/examples/device/audio_4_channel_mic_freertos/README.md @@ -6,9 +6,10 @@ $ cd /tinyusb/examples/device/audio_4_channel_mic_freertos ``` -3. Run make in project directory specifying the board +3. Run cmake in project directory specifying the board ``` -$ make BOARD=espressif_s3_devkitc all +$ cmake -DBOARD=espressif_s3_devkitc -B build -G Ninja . +$ ninja.exe -C build ``` 4. Flash the binary onto the esp32-s3 by copy-paste of the full command output by the esp-idf build system replacing **(PORT)** with eg. /dev/ttyUSB0 diff --git a/examples/device/audio_4_channel_mic_freertos/sdkconfig.defaults b/examples/device/audio_4_channel_mic_freertos/sdkconfig.defaults new file mode 100644 index 000000000..83871619e --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/sdkconfig.defaults @@ -0,0 +1,3 @@ +CONFIG_IDF_CMAKE=y +CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt index ae9b57f1f..83babce12 100644 --- a/examples/device/audio_4_channel_mic_freertos/skip.txt +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -1,3 +1,4 @@ mcu:SAMD11 mcu:SAME5X -mcu:SAMG \ No newline at end of file +mcu:SAMG +family:broadcom_64bit \ No newline at end of file diff --git a/examples/device/audio_4_channel_mic_freertos/src/CMakeLists.txt b/examples/device/audio_4_channel_mic_freertos/src/CMakeLists.txt index 29e46d979..cef2b46ee 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/CMakeLists.txt +++ b/examples/device/audio_4_channel_mic_freertos/src/CMakeLists.txt @@ -1,27 +1,4 @@ +# This file is for ESP-IDF only idf_component_register(SRCS "main.c" "usb_descriptors.c" - INCLUDE_DIRS "." - REQUIRES freertos soc) - -file(TO_NATIVE_PATH "${TOP}/hw/bsp/${FAMILY}/boards/${BOARD}/board.cmake" board_cmake) - -if(EXISTS ${board_cmake}) - include(${board_cmake}) -endif() - -target_include_directories(${COMPONENT_TARGET} PUBLIC - "${TOP}/hw" - "${TOP}/src" -) - -target_compile_definitions(${COMPONENT_TARGET} PUBLIC - ESP_PLATFORM -) - -target_sources(${COMPONENT_TARGET} PUBLIC - "${TOP}/src/tusb.c" - "${TOP}/src/common/tusb_fifo.c" - "${TOP}/src/device/usbd.c" - "${TOP}/src/device/usbd_control.c" - "${TOP}/src/class/audio/audio_device.c" - "${TOP}/src/portable/espressif/esp32sx/dcd_esp32sx.c" -) \ No newline at end of file + INCLUDE_DIRS "." + REQUIRES boards tinyusb_src) diff --git a/examples/device/audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/device/audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h index ccb620720..6cc7a6577 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h +++ b/examples/device/audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -42,6 +42,9 @@ * See http://www.freertos.org/a00110.html. *----------------------------------------------------------*/ +// skip if included from IAR assembler +#ifndef __IASMARM__ + // Include MCU header #include "bsp/board_mcu.h" @@ -53,9 +56,12 @@ #if CFG_TUSB_MCU == OPT_MCU_MM32F327X extern u32 SystemCoreClock; #else + // FIXME cause redundant-decls warnings extern uint32_t SystemCoreClock; #endif +#endif + /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 @@ -68,14 +74,14 @@ #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) -#define configTOTAL_HEAP_SIZE ( 0*1024 ) // dynamic is not used +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 -#define configQUEUE_REGISTRY_SIZE 2 +#define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 @@ -90,6 +96,7 @@ #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -124,29 +131,12 @@ #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 -/* Define to trap errors during development. */ -// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 -#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) - #define configASSERT(_exp) \ - do {\ - if ( !(_exp) ) { \ - volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ - if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ - taskDISABLE_INTERRUPTS(); \ - __asm("BKPT #0\n"); \ - }\ - }\ - } while(0) -#else - #define configASSERT( x ) -#endif - #ifdef __RX__ /* Renesas RX series */ -#define vSoftwareInterruptISR INT_Excep_ICU_SWINT -#define vTickISR INT_Excep_CMT0_CMI0 -#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) -#define configKERNEL_INTERRUPT_PRIORITY 1 +#define vSoftwareInterruptISR INT_Excep_ICU_SWINT +#define vTickISR INT_Excep_CMT0_CMI0 +#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) +#define configKERNEL_INTERRUPT_PRIORITY 1 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 #else @@ -162,9 +152,18 @@ #if defined(__NVIC_PRIO_BITS) // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h #define configPRIO_BITS __NVIC_PRIO_BITS + #elif defined(__ECLIC_INTCTLBITS) // RISC-V Bumblebee core from nuclei #define configPRIO_BITS __ECLIC_INTCTLBITS + +#elif defined(__IASMARM__) + // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. + // Therefore we will hard coded it to minimum value of 2 to get pass ci build. + // IAR user must update this to correct value of the target MCU + #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" + #define configPRIO_BITS 2 + #else #error "FreeRTOS configPRIO_BITS to be defined" #endif diff --git a/examples/device/audio_4_channel_mic_freertos/src/freertos_hook.c b/examples/device/audio_4_channel_mic_freertos/src/freertos_hook.c new file mode 100644 index 000000000..4920e3fae --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/src/freertos_hook.c @@ -0,0 +1,115 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "FreeRTOS.h" +#include "task.h" +#include "common/tusb_common.h" + + +void vApplicationMallocFailedHook(void) +{ + taskDISABLE_INTERRUPTS(); + TU_ASSERT(false, ); +} + +void vApplicationStackOverflowHook(xTaskHandle pxTask, char *pcTaskName) +{ + (void) pxTask; + (void) pcTaskName; + + taskDISABLE_INTERRUPTS(); + TU_ASSERT(false, ); +} + +/* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an + * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is + * used by the Idle task. */ +void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) +{ + /* If the buffers to be provided to the Idle task are declared inside this + * function then they must be declared static - otherwise they will be allocated on + * the stack and so not exists after this function exits. */ + static StaticTask_t xIdleTaskTCB; + static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; +} + +/* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the + * application must provide an implementation of vApplicationGetTimerTaskMemory() + * to provide the memory that is used by the Timer service task. */ +void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) +{ + /* If the buffers to be provided to the Timer task are declared inside this + * function then they must be declared static - otherwise they will be allocated on + * the stack and so not exists after this function exits. */ + static StaticTask_t xTimerTaskTCB; + static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Timer + task's state will be stored. */ + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + + /* Pass out the array that will be used as the Timer task's stack. */ + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + + /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */ + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; +} + +#if CFG_TUSB_MCU == OPT_MCU_RX63X | CFG_TUSB_MCU == OPT_MCU_RX65X +#include "iodefine.h" +void vApplicationSetupTimerInterrupt(void) +{ + /* Enable CMT0 */ + unsigned short oldPRCR = SYSTEM.PRCR.WORD; + SYSTEM.PRCR.WORD = (0xA5u<<8) | TU_BIT(1); + MSTP(CMT0) = 0; + SYSTEM.PRCR.WORD = (0xA5u<<8) | oldPRCR; + + CMT0.CMCNT = 0; + CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128); + CMT0.CMCR.WORD = TU_BIT(6) | 2; + IR(CMT0, CMI0) = 0; + IPR(CMT0, CMI0) = configKERNEL_INTERRUPT_PRIORITY; + IEN(CMT0, CMI0) = 1; + CMT.CMSTR0.BIT.STR0 = 1; +} +#endif diff --git a/examples/device/audio_4_channel_mic_freertos/src/main.c b/examples/device/audio_4_channel_mic_freertos/src/main.c index 3b9795946..980b9540b 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/main.c +++ b/examples/device/audio_4_channel_mic_freertos/src/main.c @@ -35,19 +35,30 @@ #include #include -#include "bsp/board.h" +#include "bsp/board_api.h" #include "tusb.h" -// ESP-IDF need "freertos/" prefix in include path. -// CFG_TUSB_OS_INC_PATH should be defined accordingly. -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" -#include "freertos/queue.h" -#include "freertos/task.h" -#include "freertos/timers.h" - -#define USBD_STACK_SIZE 4096 - +#if TUP_MCU_ESPRESSIF + // ESP-IDF need "freertos/" prefix in include path. + // CFG_TUSB_OS_INC_PATH should be defined accordingly. + #include "freertos/FreeRTOS.h" + #include "freertos/semphr.h" + #include "freertos/queue.h" + #include "freertos/task.h" + #include "freertos/timers.h" + + #define USBD_STACK_SIZE 4096 +#else + + #include "FreeRTOS.h" + #include "semphr.h" + #include "queue.h" + #include "task.h" + #include "timers.h" + + // Increase stack size when debug log is enabled + #define USBD_STACK_SIZE (4*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) +#endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES @@ -112,8 +123,12 @@ int main(void) sampleFreqRng.subrange[0].bMax = AUDIO_SAMPLE_RATE; sampleFreqRng.subrange[0].bRes = 0; +#if configSUPPORT_STATIC_ALLOCATION // Create a task for tinyusb device stack - (void) xTaskCreateStatic( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); + xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); +#else + xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); +#endif // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) @@ -136,9 +151,14 @@ void usb_device_task(void* param) { (void) param; + // init device stack on configured roothub port // This should be called after scheduler/kernel is started. // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. - tusb_init(); + tud_init(BOARD_TUD_RHPORT); + + if (board_init_after_tusb) { + board_init_after_tusb(); + } // RTOS forever loop while (1) diff --git a/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h b/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h index f13865084..010315c27 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h +++ b/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h @@ -30,6 +30,20 @@ extern "C" { #endif +//--------------------------------------------------------------------+ +// Board Specific Configuration +//--------------------------------------------------------------------+ + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_TUD_RHPORT +#define BOARD_TUD_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUD_MAX_SPEED +#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- @@ -39,32 +53,25 @@ extern "C" { #error CFG_TUSB_MCU must be defined #endif -// RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 -#endif - -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED -#endif - -#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE - +// This examples use FreeRTOS #ifndef CFG_TUSB_OS - #define CFG_TUSB_OS OPT_OS_FREERTOS +#define CFG_TUSB_OS OPT_OS_FREERTOS #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) - #define CFG_TUSB_OS_INC_PATH freertos/ +#if TUP_MCU_ESPRESSIF +#define CFG_TUSB_OS_INC_PATH freertos/ #endif #ifndef CFG_TUSB_DEBUG - #define CFG_TUSB_DEBUG 0 +#define CFG_TUSB_DEBUG 0 #endif -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 +// Enable Device stack +#define CFG_TUD_ENABLED 1 + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put @@ -78,7 +85,7 @@ extern "C" { #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- @@ -90,11 +97,11 @@ extern "C" { #endif //------------- CLASS -------------// +#define CFG_TUD_AUDIO 1 #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 -#define CFG_TUD_AUDIO 1 #define CFG_TUD_VENDOR 0 //-------------------------------------------------------------------- diff --git a/examples/device/audio_test_freertos/CMakeLists.txt b/examples/device/audio_test_freertos/CMakeLists.txt index 639dde99a..eb22014fb 100644 --- a/examples/device/audio_test_freertos/CMakeLists.txt +++ b/examples/device/audio_test_freertos/CMakeLists.txt @@ -1,22 +1,34 @@ -cmake_minimum_required(VERSION 3.5) - -# TOP is absolute path to root directory of TinyUSB git repo -# needed for esp32sx build. TOOD could be removed later on -set(TOP "../../..") -get_filename_component(TOP "${TOP}" REALPATH) +cmake_minimum_required(VERSION 3.17) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) # gets PROJECT name for the example (e.g. -) family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) -project(${PROJECT}) +project(${PROJECT} C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) -# Check for -DFAMILY= -if(FAMILY MATCHES "^esp32s[2-3]") -else() - message(FATAL_ERROR "Invalid FAMILY specified: ${FAMILY}") +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() endif() + +add_executable(${PROJECT}) + +# Example source +target_sources(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/freertos_hook.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c + ) + +# Example include +target_include_directories(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src + ) + +# Configure compilation flags and libraries for the example with FreeRTOS. +# See the corresponding function in hw/bsp/FAMILY/family.cmake for details. +family_configure_device_example(${PROJECT} freertos) diff --git a/examples/device/audio_test_freertos/Makefile b/examples/device/audio_test_freertos/Makefile index e5b88df5e..48a3148f8 100644 --- a/examples/device/audio_test_freertos/Makefile +++ b/examples/device/audio_test_freertos/Makefile @@ -1,22 +1,19 @@ -DEPS_SUBMODULES += lib/FreeRTOS-Kernel - -include ../../../tools/top.mk -include ../../make.mk +include ../../build_system/make/make.mk FREERTOS_SRC = lib/FreeRTOS-Kernel +FREERTOS_PORTABLE_PATH = $(FREERTOS_SRC)/portable/$(if $(findstring iar,$(TOOLCHAIN)),IAR,GCC) INC += \ src \ src/FreeRTOSConfig \ $(TOP)/hw \ $(TOP)/$(FREERTOS_SRC)/include \ - $(TOP)/$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT) - + $(TOP)/$(FREERTOS_PORTABLE_SRC) \ + # Example source EXAMPLE_SOURCE = \ src/freertos_hook.c \ src/main.c \ - src/msc_disk.c \ src/usb_descriptors.c SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) @@ -27,12 +24,15 @@ SRC_C += \ $(FREERTOS_SRC)/queue.c \ $(FREERTOS_SRC)/tasks.c \ $(FREERTOS_SRC)/timers.c \ - $(subst ../../../,,$(wildcard ../../../$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT)/*.c)) + $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.c)) + +SRC_S += \ + $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.s)) # Suppress FreeRTOS warnings -CFLAGS += -Wno-error=cast-qual +CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls # FreeRTOS (lto + Os) linker issue LDFLAGS += -Wl,--undefined=vTaskSwitchContext -include ../../rules.mk \ No newline at end of file +include ../../build_system/make/rules.mk \ No newline at end of file diff --git a/examples/device/audio_test_freertos/README.md b/examples/device/audio_test_freertos/README.md index 077a2a1b6..dd70af44b 100644 --- a/examples/device/audio_test_freertos/README.md +++ b/examples/device/audio_test_freertos/README.md @@ -6,9 +6,10 @@ $ cd /tinyusb/examples/device/audio_test_freertos ``` -3. Run make in project directory specifying the board +3. Run cmake in project directory specifying the board ``` -$ make BOARD=espressif_s3_devkitc all +$ cmake -DBOARD=espressif_s3_devkitc -B build -G Ninja . +$ ninja.exe -C build ``` 4. Flash the binary onto the esp32-s3 by copy-paste of the full command output by the esp-idf build system replacing **(PORT)** with eg. /dev/ttyUSB0 diff --git a/examples/device/audio_test_freertos/sdkconfig.defaults b/examples/device/audio_test_freertos/sdkconfig.defaults new file mode 100644 index 000000000..83871619e --- /dev/null +++ b/examples/device/audio_test_freertos/sdkconfig.defaults @@ -0,0 +1,3 @@ +CONFIG_IDF_CMAKE=y +CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y diff --git a/examples/device/audio_test_freertos/src/CMakeLists.txt b/examples/device/audio_test_freertos/src/CMakeLists.txt index 29e46d979..cef2b46ee 100644 --- a/examples/device/audio_test_freertos/src/CMakeLists.txt +++ b/examples/device/audio_test_freertos/src/CMakeLists.txt @@ -1,27 +1,4 @@ +# This file is for ESP-IDF only idf_component_register(SRCS "main.c" "usb_descriptors.c" - INCLUDE_DIRS "." - REQUIRES freertos soc) - -file(TO_NATIVE_PATH "${TOP}/hw/bsp/${FAMILY}/boards/${BOARD}/board.cmake" board_cmake) - -if(EXISTS ${board_cmake}) - include(${board_cmake}) -endif() - -target_include_directories(${COMPONENT_TARGET} PUBLIC - "${TOP}/hw" - "${TOP}/src" -) - -target_compile_definitions(${COMPONENT_TARGET} PUBLIC - ESP_PLATFORM -) - -target_sources(${COMPONENT_TARGET} PUBLIC - "${TOP}/src/tusb.c" - "${TOP}/src/common/tusb_fifo.c" - "${TOP}/src/device/usbd.c" - "${TOP}/src/device/usbd_control.c" - "${TOP}/src/class/audio/audio_device.c" - "${TOP}/src/portable/espressif/esp32sx/dcd_esp32sx.c" -) \ No newline at end of file + INCLUDE_DIRS "." + REQUIRES boards tinyusb_src) diff --git a/examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h index ccb620720..6cc7a6577 100644 --- a/examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h +++ b/examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -42,6 +42,9 @@ * See http://www.freertos.org/a00110.html. *----------------------------------------------------------*/ +// skip if included from IAR assembler +#ifndef __IASMARM__ + // Include MCU header #include "bsp/board_mcu.h" @@ -53,9 +56,12 @@ #if CFG_TUSB_MCU == OPT_MCU_MM32F327X extern u32 SystemCoreClock; #else + // FIXME cause redundant-decls warnings extern uint32_t SystemCoreClock; #endif +#endif + /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 @@ -68,14 +74,14 @@ #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) -#define configTOTAL_HEAP_SIZE ( 0*1024 ) // dynamic is not used +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 -#define configQUEUE_REGISTRY_SIZE 2 +#define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 @@ -90,6 +96,7 @@ #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -124,29 +131,12 @@ #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 -/* Define to trap errors during development. */ -// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 -#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) - #define configASSERT(_exp) \ - do {\ - if ( !(_exp) ) { \ - volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ - if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ - taskDISABLE_INTERRUPTS(); \ - __asm("BKPT #0\n"); \ - }\ - }\ - } while(0) -#else - #define configASSERT( x ) -#endif - #ifdef __RX__ /* Renesas RX series */ -#define vSoftwareInterruptISR INT_Excep_ICU_SWINT -#define vTickISR INT_Excep_CMT0_CMI0 -#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) -#define configKERNEL_INTERRUPT_PRIORITY 1 +#define vSoftwareInterruptISR INT_Excep_ICU_SWINT +#define vTickISR INT_Excep_CMT0_CMI0 +#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) +#define configKERNEL_INTERRUPT_PRIORITY 1 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 #else @@ -162,9 +152,18 @@ #if defined(__NVIC_PRIO_BITS) // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h #define configPRIO_BITS __NVIC_PRIO_BITS + #elif defined(__ECLIC_INTCTLBITS) // RISC-V Bumblebee core from nuclei #define configPRIO_BITS __ECLIC_INTCTLBITS + +#elif defined(__IASMARM__) + // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. + // Therefore we will hard coded it to minimum value of 2 to get pass ci build. + // IAR user must update this to correct value of the target MCU + #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" + #define configPRIO_BITS 2 + #else #error "FreeRTOS configPRIO_BITS to be defined" #endif diff --git a/examples/device/audio_test_freertos/src/freertos_hook.c b/examples/device/audio_test_freertos/src/freertos_hook.c new file mode 100644 index 000000000..4920e3fae --- /dev/null +++ b/examples/device/audio_test_freertos/src/freertos_hook.c @@ -0,0 +1,115 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "FreeRTOS.h" +#include "task.h" +#include "common/tusb_common.h" + + +void vApplicationMallocFailedHook(void) +{ + taskDISABLE_INTERRUPTS(); + TU_ASSERT(false, ); +} + +void vApplicationStackOverflowHook(xTaskHandle pxTask, char *pcTaskName) +{ + (void) pxTask; + (void) pcTaskName; + + taskDISABLE_INTERRUPTS(); + TU_ASSERT(false, ); +} + +/* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an + * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is + * used by the Idle task. */ +void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) +{ + /* If the buffers to be provided to the Idle task are declared inside this + * function then they must be declared static - otherwise they will be allocated on + * the stack and so not exists after this function exits. */ + static StaticTask_t xIdleTaskTCB; + static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; +} + +/* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the + * application must provide an implementation of vApplicationGetTimerTaskMemory() + * to provide the memory that is used by the Timer service task. */ +void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) +{ + /* If the buffers to be provided to the Timer task are declared inside this + * function then they must be declared static - otherwise they will be allocated on + * the stack and so not exists after this function exits. */ + static StaticTask_t xTimerTaskTCB; + static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Timer + task's state will be stored. */ + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + + /* Pass out the array that will be used as the Timer task's stack. */ + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + + /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */ + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; +} + +#if CFG_TUSB_MCU == OPT_MCU_RX63X | CFG_TUSB_MCU == OPT_MCU_RX65X +#include "iodefine.h" +void vApplicationSetupTimerInterrupt(void) +{ + /* Enable CMT0 */ + unsigned short oldPRCR = SYSTEM.PRCR.WORD; + SYSTEM.PRCR.WORD = (0xA5u<<8) | TU_BIT(1); + MSTP(CMT0) = 0; + SYSTEM.PRCR.WORD = (0xA5u<<8) | oldPRCR; + + CMT0.CMCNT = 0; + CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128); + CMT0.CMCR.WORD = TU_BIT(6) | 2; + IR(CMT0, CMI0) = 0; + IPR(CMT0, CMI0) = configKERNEL_INTERRUPT_PRIORITY; + IEN(CMT0, CMI0) = 1; + CMT.CMSTR0.BIT.STR0 = 1; +} +#endif diff --git a/examples/device/audio_test_freertos/src/main.c b/examples/device/audio_test_freertos/src/main.c index 5744b1b48..f32e3e5a6 100644 --- a/examples/device/audio_test_freertos/src/main.c +++ b/examples/device/audio_test_freertos/src/main.c @@ -35,19 +35,32 @@ #include #include -#include "bsp/board.h" +#include "bsp/board_api.h" #include "tusb.h" -// ESP-IDF need "freertos/" prefix in include path. -// CFG_TUSB_OS_INC_PATH should be defined accordingly. -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" -#include "freertos/queue.h" -#include "freertos/task.h" -#include "freertos/timers.h" - -#define USBD_STACK_SIZE 4096 +#if TUP_MCU_ESPRESSIF + // ESP-IDF need "freertos/" prefix in include path. + // CFG_TUSB_OS_INC_PATH should be defined accordingly. + #include "freertos/FreeRTOS.h" + #include "freertos/semphr.h" + #include "freertos/queue.h" + #include "freertos/task.h" + #include "freertos/timers.h" + + #define USBD_STACK_SIZE 4096 +#else + + #include "FreeRTOS.h" + #include "semphr.h" + #include "queue.h" + #include "task.h" + #include "timers.h" + + // Increase stack size when debug log is enabled + #define USBD_STACK_SIZE (4*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) +#endif +#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES @@ -68,12 +81,16 @@ enum { BLINK_SUSPENDED = 2500, }; -// static timer -StaticTimer_t blinky_tmdef; -TimerHandle_t blinky_tm; +// static task +#if configSUPPORT_STATIC_ALLOCATION +StackType_t blinky_stack[BLINKY_STACK_SIZE]; +StaticTask_t blinky_taskdef; + StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; +#endif +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; // Audio controls // Current states @@ -90,7 +107,7 @@ audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range stat uint16_t test_buffer_audio[CFG_TUD_AUDIO_EP_SZ_IN/2]; uint16_t startVal = 0; -void led_blinky_cb(TimerHandle_t xTimer); +void led_blinking_task(void* param); void usb_device_task(void* param); void audio_task(void); @@ -99,10 +116,6 @@ int main(void) { board_init(); - // soft timer for blinky - blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef); - xTimerStart(blinky_tm, 0); - // Init values sampFreq = AUDIO_SAMPLE_RATE; clkValid = 1; @@ -112,8 +125,16 @@ int main(void) sampleFreqRng.subrange[0].bMax = AUDIO_SAMPLE_RATE; sampleFreqRng.subrange[0].bRes = 0; +#if configSUPPORT_STATIC_ALLOCATION + // blinky task + xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); + // Create a task for tinyusb device stack - (void) xTaskCreateStatic( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); + xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); +#else + xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); + xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); +#endif // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) @@ -136,9 +157,14 @@ void usb_device_task(void* param) { (void) param; + // init device stack on configured roothub port // This should be called after scheduler/kernel is started. // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. - tusb_init(); + tud_init(BOARD_TUD_RHPORT); + + if (board_init_after_tusb) { + board_init_after_tusb(); + } // RTOS forever loop while (1) @@ -153,30 +179,26 @@ void usb_device_task(void* param) //--------------------------------------------------------------------+ // Invoked when device is mounted -void tud_mount_cb(void) -{ - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); +void tud_mount_cb(void) { + blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted -void tud_umount_cb(void) -{ - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); +void tud_umount_cb(void) { + blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus -void tud_suspend_cb(bool remote_wakeup_en) -{ +void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_SUSPENDED), 0); + blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed -void tud_resume_cb(void) -{ - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); +void tud_resume_cb(void) { + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ @@ -476,11 +498,17 @@ bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const ///--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ -void led_blinky_cb(TimerHandle_t xTimer) -{ - (void) xTimer; +void led_blinking_task(void* param) { + (void) param; + static uint32_t start_ms = 0; static bool led_state = false; - board_led_write(led_state); - led_state = 1 - led_state; // toggle + while (1) { + // Blink every interval ms + vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); + start_ms += blink_interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle + } } diff --git a/examples/device/audio_test_freertos/src/plot_audio_samples.py b/examples/device/audio_test_freertos/src/plot_audio_samples.py index 6e3c4978e..6f1518be5 100644 --- a/examples/device/audio_test_freertos/src/plot_audio_samples.py +++ b/examples/device/audio_test_freertos/src/plot_audio_samples.py @@ -10,7 +10,7 @@ if __name__ == '__main__': # print(sd.query_devices()) fs = 48000 # Sample rate - duration = 100e-3 # Duration of recording + duration = 1000e-3 # Duration of recording if platform.system() == 'Windows': # MME is needed since there are more than one MicNode device APIs (at least in Windows) -- cgit v1.3.1 From 7dd26877de2ed85a608190a76acf960e256c88bf Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Apr 2024 22:16:30 +0200 Subject: Update audio_test & audio_test_freertos examples to work with high-speed. --- examples/device/audio_test/src/main.c | 10 +++------- examples/device/audio_test/src/tusb_config.h | 7 ++++--- examples/device/audio_test_freertos/src/main.c | 10 +++------- examples/device/audio_test_freertos/src/tusb_config.h | 7 ++++--- 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/examples/device/audio_test/src/main.c b/examples/device/audio_test/src/main.c index 06783ccfb..f79bb4468 100644 --- a/examples/device/audio_test/src/main.c +++ b/examples/device/audio_test/src/main.c @@ -42,10 +42,6 @@ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ -#ifndef AUDIO_SAMPLE_RATE -#define AUDIO_SAMPLE_RATE 48000 -#endif - /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted @@ -90,12 +86,12 @@ int main(void) } // Init values - sampFreq = AUDIO_SAMPLE_RATE; + sampFreq = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; clkValid = 1; sampleFreqRng.wNumSubRanges = 1; - sampleFreqRng.subrange[0].bMin = AUDIO_SAMPLE_RATE; - sampleFreqRng.subrange[0].bMax = AUDIO_SAMPLE_RATE; + sampleFreqRng.subrange[0].bMin = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; + sampleFreqRng.subrange[0].bMax = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; sampleFreqRng.subrange[0].bRes = 0; while (1) diff --git a/examples/device/audio_test/src/tusb_config.h b/examples/device/audio_test/src/tusb_config.h index 9f38612a9..8c021e23c 100644 --- a/examples/device/audio_test/src/tusb_config.h +++ b/examples/device/audio_test/src/tusb_config.h @@ -106,6 +106,7 @@ extern "C" { //-------------------------------------------------------------------- // Have a look into audio_device.h for all configurations +#define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000 #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_ONE_CH_DESC_LEN #define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 // Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes) @@ -114,9 +115,9 @@ extern "C" { #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor! -#define CFG_TUD_AUDIO_EP_SZ_IN (48 + 1) * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX // 48 Samples (48 kHz) x 2 Bytes/Sample x CFG_TUD_AUDIO_N_CHANNELS_TX Channels - One extra sample is needed for asynchronous transfer adjustment, see feedback EP -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN // Maximum EP IN size for all AS alternate settings used -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN + 1 +#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 8 : 1) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device #ifdef __cplusplus } diff --git a/examples/device/audio_test_freertos/src/main.c b/examples/device/audio_test_freertos/src/main.c index f32e3e5a6..cf1c336a9 100644 --- a/examples/device/audio_test_freertos/src/main.c +++ b/examples/device/audio_test_freertos/src/main.c @@ -66,10 +66,6 @@ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ -#ifndef AUDIO_SAMPLE_RATE -#define AUDIO_SAMPLE_RATE 48000 -#endif - /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted @@ -117,12 +113,12 @@ int main(void) board_init(); // Init values - sampFreq = AUDIO_SAMPLE_RATE; + sampFreq = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; clkValid = 1; sampleFreqRng.wNumSubRanges = 1; - sampleFreqRng.subrange[0].bMin = AUDIO_SAMPLE_RATE; - sampleFreqRng.subrange[0].bMax = AUDIO_SAMPLE_RATE; + sampleFreqRng.subrange[0].bMin = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; + sampleFreqRng.subrange[0].bMax = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; sampleFreqRng.subrange[0].bRes = 0; #if configSUPPORT_STATIC_ALLOCATION diff --git a/examples/device/audio_test_freertos/src/tusb_config.h b/examples/device/audio_test_freertos/src/tusb_config.h index 598706e78..61ddadb9f 100644 --- a/examples/device/audio_test_freertos/src/tusb_config.h +++ b/examples/device/audio_test_freertos/src/tusb_config.h @@ -102,6 +102,7 @@ extern "C" { //-------------------------------------------------------------------- // Have a look into audio_device.h for all configurations +#define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000 #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_ONE_CH_DESC_LEN #define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 // Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes) @@ -110,9 +111,9 @@ extern "C" { #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor! -#define CFG_TUD_AUDIO_EP_SZ_IN 48 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX // 48 Samples (48 kHz) x 2 Bytes/Sample x 1 Channel -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN // Maximum EP IN size for all AS alternate settings used -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN + 1 +#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 8 : 1) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device #ifdef __cplusplus } -- cgit v1.3.1 From bb89a5a5bf0cb13f895675f4480801e52d822203 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Apr 2024 22:17:10 +0200 Subject: audio_test_freertos : merge changes from audio_test. --- examples/device/audio_test_freertos/src/main.c | 12 ++-- .../device/audio_test_freertos/src/tusb_config.h | 48 +++++++------ .../audio_test_freertos/src/usb_descriptors.c | 78 +++++++++++++--------- 3 files changed, 82 insertions(+), 56 deletions(-) diff --git a/examples/device/audio_test_freertos/src/main.c b/examples/device/audio_test_freertos/src/main.c index cf1c336a9..903c97d20 100644 --- a/examples/device/audio_test_freertos/src/main.c +++ b/examples/device/audio_test_freertos/src/main.c @@ -100,7 +100,7 @@ audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state // Audio test data -uint16_t test_buffer_audio[CFG_TUD_AUDIO_EP_SZ_IN/2]; +uint16_t test_buffer_audio[(CFG_TUD_AUDIO_EP_SZ_IN - 2) / 2]; uint16_t startVal = 0; void led_blinking_task(void* param); @@ -283,7 +283,7 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * // Request uses format layout 2 TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t)); - volume[channelNum] = ((audio_control_cur_2_t*) pBuff)->bCur; + volume[channelNum] = (uint16_t) ((audio_control_cur_2_t*) pBuff)->bCur; TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; @@ -352,7 +352,7 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * // Those are dummy values for now ret.bNrChannels = 1; - ret.bmChannelConfig = 0; + ret.bmChannelConfig = (audio_channel_config_t) 0; ret.iChannelNames = 0; TU_LOG2(" Get terminal connector\r\n"); @@ -461,7 +461,7 @@ bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, u (void) ep_in; (void) cur_alt_setting; - tud_audio_write ((uint8_t *)test_buffer_audio, CFG_TUD_AUDIO_EP_SZ_IN); + tud_audio_write ((uint8_t *)test_buffer_audio, CFG_TUD_AUDIO_EP_SZ_IN - 2); return true; } @@ -474,7 +474,7 @@ bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uin (void) ep_in; (void) cur_alt_setting; - for (size_t cnt = 0; cnt < CFG_TUD_AUDIO_EP_SZ_IN/2; cnt++) + for (size_t cnt = 0; cnt < (CFG_TUD_AUDIO_EP_SZ_IN - 2) / 2; cnt++) { test_buffer_audio[cnt] = startVal++; } @@ -491,7 +491,7 @@ bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const return true; } -///--------------------------------------------------------------------+ +//--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void* param) { diff --git a/examples/device/audio_test_freertos/src/tusb_config.h b/examples/device/audio_test_freertos/src/tusb_config.h index 61ddadb9f..8b376a4c3 100644 --- a/examples/device/audio_test_freertos/src/tusb_config.h +++ b/examples/device/audio_test_freertos/src/tusb_config.h @@ -30,39 +30,49 @@ extern "C" { #endif +//--------------------------------------------------------------------+ +// Board Specific Configuration +//--------------------------------------------------------------------+ + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_TUD_RHPORT +#define BOARD_TUD_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUD_MAX_SPEED +#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -// RHPort number used for device can be defined by board.mk, default to port 0 -#ifndef BOARD_DEVICE_RHPORT_NUM - #define BOARD_DEVICE_RHPORT_NUM 0 -#endif - -#ifndef BOARD_DEVICE_RHPORT_SPEED - #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED +#error CFG_TUSB_MCU must be defined #endif -#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE - +// This examples use FreeRTOS #ifndef CFG_TUSB_OS - #define CFG_TUSB_OS OPT_OS_FREERTOS +#define CFG_TUSB_OS OPT_OS_FREERTOS #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) - #define CFG_TUSB_OS_INC_PATH freertos/ +#if TUP_MCU_ESPRESSIF +#define CFG_TUSB_OS_INC_PATH freertos/ #endif #ifndef CFG_TUSB_DEBUG - #define CFG_TUSB_DEBUG 0 +#define CFG_TUSB_DEBUG 0 #endif +// Enable Device stack +#define CFG_TUD_ENABLED 1 + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED + // CFG_TUSB_DEBUG is defined by compiler in DEBUG build // #define CFG_TUSB_DEBUG 0 @@ -74,11 +84,11 @@ extern "C" { * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION - #define CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN - #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- @@ -90,11 +100,11 @@ extern "C" { #endif //------------- CLASS -------------// +#define CFG_TUD_AUDIO 1 #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 -#define CFG_TUD_AUDIO 1 #define CFG_TUD_VENDOR 0 //-------------------------------------------------------------------- diff --git a/examples/device/audio_test_freertos/src/usb_descriptors.c b/examples/device/audio_test_freertos/src/usb_descriptors.c index b8df75e71..9864377f6 100644 --- a/examples/device/audio_test_freertos/src/usb_descriptors.c +++ b/examples/device/audio_test_freertos/src/usb_descriptors.c @@ -23,6 +23,7 @@ * */ +#include "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. @@ -44,7 +45,7 @@ tusb_desc_device_t const desc_device = .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, - // Use Interface Association Descriptor (IAD) for CDC + // Use Interface Association Descriptor (IAD) for Audio // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, @@ -96,11 +97,11 @@ enum uint8_t const desc_configuration[] = { - // Interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), - // Interface number, string index, EP Out & EP In address, EP size - TUD_AUDIO_MIC_ONE_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) + // Interface number, string index, EP Out & EP In address, EP size + TUD_AUDIO_MIC_ONE_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) }; // Invoked when received GET CONFIGURATION DESCRIPTOR @@ -116,50 +117,65 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index) // String Descriptors //--------------------------------------------------------------------+ +// String Descriptor Index +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, +}; + // array of pointer to string descriptors char const* string_desc_arr [] = { - (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) - "PaniRCorp", // 1: Manufacturer - "MicNode", // 2: Product - "123456", // 3: Serials, should use chip ID - "UAC2", // 4: Audio Interface + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "PaniRCorp", // 1: Manufacturer + "MicNode", // 2: Product + NULL, // 3: Serials will use unique ID if possible + "UAC2", // 4: Audio Interface + }; -static uint16_t _desc_str[32]; +static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete -uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) -{ +uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; + size_t chr_count; + + switch ( index ) { + case STRID_LANGID: + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + break; - uint8_t chr_count; + case STRID_SERIAL: + chr_count = board_usb_get_serial(_desc_str + 1, 32); + break; - if ( index == 0) - { - memcpy(&_desc_str[1], string_desc_arr[0], 2); - chr_count = 1; - }else - { - // Convert ASCII string into UTF-16 + default: + // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. + // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; - const char* str = string_desc_arr[index]; + const char *str = string_desc_arr[index]; - // Cap at max char - chr_count = strlen(str); - if ( chr_count > 31 ) chr_count = 31; + // Cap at max char + chr_count = strlen(str); + size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type + if ( chr_count > max_count ) chr_count = max_count; - for(uint8_t i=0; i Date: Sun, 28 Apr 2024 00:09:06 +0200 Subject: audio_4_channel_mic_freertos : merge changes from audio_4_channel_mic. --- .../audio_4_channel_mic_freertos/CMakeLists.txt | 5 + .../sdkconfig.defaults | 1 + .../device/audio_4_channel_mic_freertos/src/main.c | 150 +++++++++++++++------ .../audio_4_channel_mic_freertos/src/tusb_config.h | 41 ++++-- .../src/usb_descriptors.c | 74 +++++----- 5 files changed, 189 insertions(+), 82 deletions(-) diff --git a/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt b/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt index eb22014fb..e8ca3751d 100644 --- a/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt +++ b/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt @@ -29,6 +29,11 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Add libm for GCC +if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_libraries(${PROJECT} PUBLIC m) +endif() + # Configure compilation flags and libraries for the example with FreeRTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT} freertos) diff --git a/examples/device/audio_4_channel_mic_freertos/sdkconfig.defaults b/examples/device/audio_4_channel_mic_freertos/sdkconfig.defaults index 83871619e..eaa9fb902 100644 --- a/examples/device/audio_4_channel_mic_freertos/sdkconfig.defaults +++ b/examples/device/audio_4_channel_mic_freertos/sdkconfig.defaults @@ -1,3 +1,4 @@ CONFIG_IDF_CMAKE=y +CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y diff --git a/examples/device/audio_4_channel_mic_freertos/src/main.c b/examples/device/audio_4_channel_mic_freertos/src/main.c index 980b9540b..7d953e71c 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/main.c +++ b/examples/device/audio_4_channel_mic_freertos/src/main.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "bsp/board_api.h" #include "tusb.h" @@ -60,13 +61,13 @@ #define USBD_STACK_SIZE (4*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif +#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE +#define AUDIO_STACK_SIZE configMINIMAL_STACK_SIZE + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ - -#ifndef AUDIO_SAMPLE_RATE -#define AUDIO_SAMPLE_RATE 48000 -#endif +#define AUDIO_SAMPLE_RATE CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE /* Blink pattern * - 250 ms : device not mounted @@ -79,12 +80,19 @@ enum { BLINK_SUSPENDED = 2500, }; -// static timer -StaticTimer_t blinky_tmdef; -TimerHandle_t blinky_tm; +// static task +#if configSUPPORT_STATIC_ALLOCATION +StackType_t blinky_stack[BLINKY_STACK_SIZE]; +StaticTask_t blinky_taskdef; + StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; +StackType_t audio_stack[AUDIO_STACK_SIZE]; +StaticTask_t audio_taskdef; +#endif + +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; // Audio controls // Current states @@ -97,23 +105,23 @@ uint8_t clkValid; audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; // Volume range state audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state -// Audio test data -uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_EP_SZ_IN/2]; // Ensure half word aligned -uint16_t samples[] = {0, 0, 0, 0}; +#if CFG_TUD_AUDIO_ENABLE_ENCODING +// Audio test data, each buffer contains 2 channels, buffer[0] for CH0-1, buffer[1] for CH1-2 +uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX*CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE/1000/CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO]; +#else +// Audio test data, 4 channels muxed together, buffer[0] for CH0, buffer[1] for CH1, buffer[2] for CH2, buffer[3] for CH3 +uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX*CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE/1000]; +#endif -void led_blinky_cb(TimerHandle_t xTimer); +void led_blinking_task(void* param); void usb_device_task(void* param); -void audio_task(void); +void audio_task(void* param); /*------------- MAIN -------------*/ int main(void) { board_init(); - // soft timer for blinky - blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef); - xTimerStart(blinky_tm, 0); - // Init values sampFreq = AUDIO_SAMPLE_RATE; clkValid = 1; @@ -123,11 +131,58 @@ int main(void) sampleFreqRng.subrange[0].bMax = AUDIO_SAMPLE_RATE; sampleFreqRng.subrange[0].bRes = 0; + // Generate dummy data +#if CFG_TUD_AUDIO_ENABLE_ENCODING + uint16_t * p_buff = i2s_dummy_buffer[0]; + uint16_t dataVal = 0; + for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++) + { + // CH0 saw wave + *p_buff++ = dataVal; + // CH1 inverted saw wave + *p_buff++ = 3200 + AUDIO_SAMPLE_RATE/1000 - dataVal; + dataVal+= 32; + } + p_buff = i2s_dummy_buffer[1]; + for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++) + { + // CH3 square wave + *p_buff++ = cnt < (AUDIO_SAMPLE_RATE/1000/2) ? 3400:5000; + // CH4 sinus wave + float t = 2*3.1415f * cnt / (AUDIO_SAMPLE_RATE/1000); + *p_buff++ = (uint16_t)((int16_t)(sinf(t) * 750) + 6000); + } +#else + uint16_t * p_buff = i2s_dummy_buffer; + uint16_t dataVal = 0; + for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++) + { + // CH0 saw wave + *p_buff++ = dataVal; + // CH1 inverted saw wave + *p_buff++ = 3200 + AUDIO_SAMPLE_RATE/1000 - dataVal; + dataVal+= 32; + // CH3 square wave + *p_buff++ = cnt < (AUDIO_SAMPLE_RATE/1000/2) ? 3400:5000; + // CH4 sinus wave + float t = 2*3.1415f * cnt / (AUDIO_SAMPLE_RATE/1000); + *p_buff++ = (uint16_t)((int16_t)(sinf(t) * 750) + 6000); + } +#endif + #if configSUPPORT_STATIC_ALLOCATION + // blinky task + xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); + // Create a task for tinyusb device stack xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); + + // Create a task for audio + xTaskCreateStatic(audio_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES-1, audio_stack, &audio_taskdef); #else + xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); + xTaskCreate(audio_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); #endif // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 @@ -175,13 +230,13 @@ void usb_device_task(void* param) // Invoked when device is mounted void tud_mount_cb(void) { - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); + blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); + blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended @@ -190,23 +245,36 @@ void tud_umount_cb(void) void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_SUSPENDED), 0); + blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // AUDIO Task //--------------------------------------------------------------------+ -void audio_task(void) +void audio_task(void* param) { - // Yet to be filled - e.g. put meas data into TX FIFOs etc. - // asm("nop"); + (void) param; + // Yet to be filled - e.g. read audio from I2S buffer. + // Here we simulate a I2S receive callback every 1ms. + while (1) { + vTaskDelay(1); +#if CFG_TUD_AUDIO_ENABLE_ENCODING + // Write I2S buffer into FIFO + for (uint8_t cnt=0; cnt < 2; cnt++) + { + tud_audio_write_support_ff(cnt, i2s_dummy_buffer[cnt], AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX); + } +#else + tud_audio_write(i2s_dummy_buffer, AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX); +#endif + } } //--------------------------------------------------------------------+ @@ -427,7 +495,8 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * { case AUDIO_CS_REQ_CUR: TU_LOG2(" Get Sample Freq.\r\n"); - return tud_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); + // Buffered control transfer is needed for IN flow control to work + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); case AUDIO_CS_REQ_RANGE: TU_LOG2(" Get Sample Freq. range\r\n"); @@ -463,7 +532,14 @@ bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, u (void) ep_in; (void) cur_alt_setting; - tud_audio_write((uint8_t*)i2s_dummy_buffer, CFG_TUD_AUDIO_EP_SZ_IN); + + // In read world application data flow is driven by I2S clock, + // both tud_audio_tx_done_pre_load_cb() & tud_audio_tx_done_post_load_cb() are hardly used. + // For example in your I2S receive callback: + // void I2S_Rx_Callback(int channel, const void* data, uint16_t samples) + // { + // tud_audio_write_support_ff(channel, data, samples * N_BYTES_PER_SAMPLE * N_CHANNEL_PER_FIFO); + // } return true; } @@ -476,14 +552,6 @@ bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uin (void) ep_in; (void) cur_alt_setting; - uint16_t* p_buff = i2s_dummy_buffer; - for (int samples_num = 0; samples_num < AUDIO_SAMPLE_RATE/1000; samples_num++) { - for (int ch=0; ch < CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX; ch++) { - *p_buff++ = samples[ch]; - samples[ch] = samples[ch]+(ch+1); - } - } - return true; } @@ -498,11 +566,17 @@ bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const ///--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ -void led_blinky_cb(TimerHandle_t xTimer) -{ - (void) xTimer; +void led_blinking_task(void* param) { + (void) param; + static uint32_t start_ms = 0; static bool led_state = false; - board_led_write(led_state); - led_state = 1 - led_state; // toggle + while (1) { + // Blink every interval ms + vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); + start_ms += blink_interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle + } } diff --git a/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h b/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h index 010315c27..88f20278b 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h +++ b/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h @@ -109,24 +109,37 @@ extern "C" { //-------------------------------------------------------------------- // Have a look into audio_device.h for all configurations +#define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000 -#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_FOUR_CH_DESC_LEN +#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_FOUR_CH_DESC_LEN -#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 -#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 +#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 +#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 -#define CFG_TUD_AUDIO_ENABLE_EP_IN 1 -#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup -#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 4 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup -#define CFG_TUD_AUDIO_EP_SZ_IN 48 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX // 48 Samples (48 kHz) x 2 Bytes/Sample x CFG_TUD_AUDIO_N_CHANNELS_TX Channels - the Windows driver always needs an extra sample per channel of space more, otherwise it complains... found by trial and error -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN +#define CFG_TUD_AUDIO_ENABLE_EP_IN 1 +#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup +#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 4 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup +#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) -#define CFG_TUD_AUDIO_ENABLE_ENCODING 0 -#define CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING 0 -#define CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX 2 // One I2S stream contains two channels, each stream is saved within one support FIFO - this value is currently fixed, the driver does not support a changing value -#define CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX) -#define CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ (CFG_TUD_AUDIO_EP_SZ_IN / CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO) +#define CFG_TUD_AUDIO_ENABLE_ENCODING 1 +#define CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL 1 + +#if CFG_TUD_AUDIO_ENABLE_ENCODING + +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN + +#define CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING 1 +#define CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX 2 // One I2S stream contains two channels, each stream is saved within one support FIFO - this value is currently fixed, the driver does not support a changing value +#define CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX) +#define CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * (CFG_TUD_AUDIO_EP_SZ_IN / CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO) // Example write FIFO every 1ms, so it should be 8 times larger for HS device + +#else + +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device + +#endif #ifdef __cplusplus } diff --git a/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c b/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c index 16355a7fc..728a5f9ce 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c +++ b/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c @@ -23,6 +23,7 @@ * */ +#include "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. @@ -44,7 +45,7 @@ tusb_desc_device_t const desc_device = .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, - // Use Interface Association Descriptor (IAD) for CDC + // Use Interface Association Descriptor (IAD) for Audio // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, @@ -96,7 +97,7 @@ enum uint8_t const desc_configuration[] = { - // Interface count, string index, total length, attribute, power in mA + // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size @@ -116,50 +117,63 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index) // String Descriptors //--------------------------------------------------------------------+ +// String Descriptor Index +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, +}; + // array of pointer to string descriptors -char const* string_desc_arr [] = -{ - (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) - "PaniRCorp", // 1: Manufacturer - "MicNode_4_Ch", // 2: Product - "123458", // 3: Serials, should use chip ID - "UAC2", // 4: Audio Interface +char const* string_desc_arr [] = { + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "PaniRCorp", // 1: Manufacturer + "MicNode_4_Ch", // 2: Product + NULL, // 3: Serials will use unique ID if possible + "UAC2", // 4: Audio Interface }; -static uint16_t _desc_str[32]; +static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete -uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) -{ +uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; + size_t chr_count; + + switch ( index ) { + case STRID_LANGID: + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + break; - uint8_t chr_count; + case STRID_SERIAL: + chr_count = board_usb_get_serial(_desc_str + 1, 32); + break; - if ( index == 0) - { - memcpy(&_desc_str[1], string_desc_arr[0], 2); - chr_count = 1; - }else - { - // Convert ASCII string into UTF-16 + default: + // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. + // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; - const char* str = string_desc_arr[index]; + const char *str = string_desc_arr[index]; - // Cap at max char - chr_count = strlen(str); - if ( chr_count > 31 ) chr_count = 31; + // Cap at max char + chr_count = strlen(str); + size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type + if ( chr_count > max_count ) chr_count = max_count; - for(uint8_t i=0; i Date: Sun, 28 Apr 2024 00:29:19 +0200 Subject: Build STM32F7 with single-point FPU. --- .../build_system/cmake/cpu/cortex-m7-fpsp.cmake | 25 ++++++++++++++++++++ examples/build_system/make/cpu/cortex-m7-fpsp.mk | 27 ++++++++++++++++++++++ hw/bsp/stm32f7/family.cmake | 2 +- hw/bsp/stm32f7/family.mk | 2 +- 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 examples/build_system/cmake/cpu/cortex-m7-fpsp.cmake create mode 100644 examples/build_system/make/cpu/cortex-m7-fpsp.mk diff --git a/examples/build_system/cmake/cpu/cortex-m7-fpsp.cmake b/examples/build_system/cmake/cpu/cortex-m7-fpsp.cmake new file mode 100644 index 000000000..b10f00fc2 --- /dev/null +++ b/examples/build_system/cmake/cpu/cortex-m7-fpsp.cmake @@ -0,0 +1,25 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mthumb + -mcpu=cortex-m7 + -mfloat-abi=hard + -mfpu=fpv5-sp-d16 + ) + set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m7 + -mfpu=fpv5-sp-d16 + ) + set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + set(TOOLCHAIN_COMMON_FLAGS + --cpu cortex-m7 + --fpu VFPv5_sp + ) + set(FREERTOS_PORT IAR_ARM_CM7 CACHE INTERNAL "") + +endif () diff --git a/examples/build_system/make/cpu/cortex-m7-fpsp.mk b/examples/build_system/make/cpu/cortex-m7-fpsp.mk new file mode 100644 index 000000000..cd42c6fb8 --- /dev/null +++ b/examples/build_system/make/cpu/cortex-m7-fpsp.mk @@ -0,0 +1,27 @@ +ifeq ($(TOOLCHAIN),gcc) + CFLAGS += \ + -mthumb \ + -mcpu=cortex-m7 \ + -mfloat-abi=hard \ + -mfpu=fpv5-sp-d16 \ + +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m7 \ + -mfpu=fpv5-sp-d16 \ + +else ifeq ($(TOOLCHAIN),iar) + CFLAGS += \ + --cpu cortex-m7 \ + --fpu VFPv5_sp \ + + ASFLAGS += \ + --cpu cortex-m7 \ + --fpu VFPv5_sp \ + +else + $(error "TOOLCHAIN is not supported") +endif + +FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM7/r0p1 diff --git a/hw/bsp/stm32f7/family.cmake b/hw/bsp/stm32f7/family.cmake index be566f2eb..17e632c40 100644 --- a/hw/bsp/stm32f7/family.cmake +++ b/hw/bsp/stm32f7/family.cmake @@ -11,7 +11,7 @@ set(CMSIS_5 ${TOP}/lib/CMSIS_5) include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up -set(CMAKE_SYSTEM_PROCESSOR cortex-m7 CACHE INTERNAL "System Processor") +set(CMAKE_SYSTEM_PROCESSOR cortex-m7-fpsp CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32F7 CACHE INTERNAL "") diff --git a/hw/bsp/stm32f7/family.mk b/hw/bsp/stm32f7/family.mk index cc21bd64e..e261b0467 100644 --- a/hw/bsp/stm32f7/family.mk +++ b/hw/bsp/stm32f7/family.mk @@ -6,7 +6,7 @@ ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= cortex-m7 +CPU_CORE ?= cortex-m7-fpsp # -------------- # Compiler Flags -- cgit v1.3.1 From ef7be4c2ffa0061aec2ea32f530a4037f7309f1e Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 28 Apr 2024 00:40:36 +0200 Subject: Fix CI. --- examples/device/CMakeLists.txt | 2 ++ examples/device/audio_4_channel_mic_freertos/Makefile | 2 +- examples/device/audio_4_channel_mic_freertos/skip.txt | 16 +++++++++++++--- examples/device/audio_4_channel_mic_freertos/src/main.c | 2 -- .../src/plot_audio_samples.py | 1 - examples/device/audio_test_freertos/Makefile | 2 +- examples/device/audio_test_freertos/README.md | 2 +- examples/device/audio_test_freertos/skip.txt | 14 ++++++++++++-- examples/device/audio_test_freertos/src/main.c | 2 -- .../device/audio_test_freertos/src/plot_audio_samples.py | 1 - examples/device/cdc_msc_freertos/skip.txt | 1 + examples/device/video_capture_2ch/skip.txt | 1 + hw/bsp/stm32l0/FreeRTOSConfig/FreeRTOSConfig.h | 2 +- 13 files changed, 33 insertions(+), 15 deletions(-) diff --git a/examples/device/CMakeLists.txt b/examples/device/CMakeLists.txt index c3671da69..638440795 100644 --- a/examples/device/CMakeLists.txt +++ b/examples/device/CMakeLists.txt @@ -8,6 +8,8 @@ family_initialize_project(tinyusb_device_examples ${CMAKE_CURRENT_LIST_DIR}) # family_add_subdirectory will filter what to actually add based on selected FAMILY family_add_subdirectory(audio_4_channel_mic) family_add_subdirectory(audio_test) +family_add_subdirectory(audio_4_channel_mic_freertos) +family_add_subdirectory(audio_test_freertos) family_add_subdirectory(audio_test_multi_rate) family_add_subdirectory(board_test) family_add_subdirectory(cdc_dual_ports) diff --git a/examples/device/audio_4_channel_mic_freertos/Makefile b/examples/device/audio_4_channel_mic_freertos/Makefile index 48a3148f8..df2cdef4e 100644 --- a/examples/device/audio_4_channel_mic_freertos/Makefile +++ b/examples/device/audio_4_channel_mic_freertos/Makefile @@ -35,4 +35,4 @@ CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls # FreeRTOS (lto + Os) linker issue LDFLAGS += -Wl,--undefined=vTaskSwitchContext -include ../../build_system/make/rules.mk \ No newline at end of file +include ../../build_system/make/rules.mk diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt index 83babce12..eb434c23b 100644 --- a/examples/device/audio_4_channel_mic_freertos/skip.txt +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -1,4 +1,14 @@ +mcu:CH32V307 +mcu:CXD56 +mcu:F1C100S +mcu:GD32VF103 +mcu:MKL25ZXX +mcu:MSP430x5xx +mcu:RP2040 mcu:SAMD11 -mcu:SAME5X -mcu:SAMG -family:broadcom_64bit \ No newline at end of file +mcu:SAMX7X +mcu:VALENTYUSB_EPTRI +mcu:RAXXX +mcu:STM32L0 +family:broadcom_32bit +family:broadcom_64bit diff --git a/examples/device/audio_4_channel_mic_freertos/src/main.c b/examples/device/audio_4_channel_mic_freertos/src/main.c index 7d953e71c..08f49326c 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/main.c +++ b/examples/device/audio_4_channel_mic_freertos/src/main.c @@ -379,8 +379,6 @@ bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_re (void) channelNum; (void) ctrlSel; (void) ep; - // return tud_control_xfer(rhport, p_request, &tmp, 1); - return false; // Yet not implemented } diff --git a/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py b/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py index 9ab15135d..8312b4e28 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py +++ b/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py @@ -31,4 +31,3 @@ if __name__ == '__main__': plt.ylabel('Amplitude') plt.title('MicNode 4 Channel') plt.show() - \ No newline at end of file diff --git a/examples/device/audio_test_freertos/Makefile b/examples/device/audio_test_freertos/Makefile index 48a3148f8..df2cdef4e 100644 --- a/examples/device/audio_test_freertos/Makefile +++ b/examples/device/audio_test_freertos/Makefile @@ -35,4 +35,4 @@ CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls # FreeRTOS (lto + Os) linker issue LDFLAGS += -Wl,--undefined=vTaskSwitchContext -include ../../build_system/make/rules.mk \ No newline at end of file +include ../../build_system/make/rules.mk diff --git a/examples/device/audio_test_freertos/README.md b/examples/device/audio_test_freertos/README.md index dd70af44b..9477fcd78 100644 --- a/examples/device/audio_test_freertos/README.md +++ b/examples/device/audio_test_freertos/README.md @@ -16,4 +16,4 @@ $ ninja.exe -C build eg. -> /home/kaspernyhus/.espressif/python_env/idf4.4_py3.8_env/bin/python ../../../../esp-idf/components/esptool_py/esptool/esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset --chip esp32s3 write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x0 _build/espressif_s3_devkitc/bootloader/bootloader.bin 0x8000 _build/espressif_s3_devkitc/partition_table/partition-table.bin 0x10000 _build/espressif_s3_devkitc/audio_test_freertos.bin \ No newline at end of file +> /home/kaspernyhus/.espressif/python_env/idf4.4_py3.8_env/bin/python ../../../../esp-idf/components/esptool_py/esptool/esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset --chip esp32s3 write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x0 _build/espressif_s3_devkitc/bootloader/bootloader.bin 0x8000 _build/espressif_s3_devkitc/partition_table/partition-table.bin 0x10000 _build/espressif_s3_devkitc/audio_test_freertos.bin diff --git a/examples/device/audio_test_freertos/skip.txt b/examples/device/audio_test_freertos/skip.txt index ae9b57f1f..a6f96b288 100644 --- a/examples/device/audio_test_freertos/skip.txt +++ b/examples/device/audio_test_freertos/skip.txt @@ -1,3 +1,13 @@ +mcu:CH32V307 +mcu:CXD56 +mcu:F1C100S +mcu:GD32VF103 +mcu:MKL25ZXX +mcu:MSP430x5xx +mcu:RP2040 mcu:SAMD11 -mcu:SAME5X -mcu:SAMG \ No newline at end of file +mcu:SAMX7X +mcu:VALENTYUSB_EPTRI +mcu:RAXXX +family:broadcom_32bit +family:broadcom_64bit diff --git a/examples/device/audio_test_freertos/src/main.c b/examples/device/audio_test_freertos/src/main.c index 903c97d20..a3751da40 100644 --- a/examples/device/audio_test_freertos/src/main.c +++ b/examples/device/audio_test_freertos/src/main.c @@ -309,8 +309,6 @@ bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_re (void) channelNum; (void) ctrlSel; (void) ep; - // return tud_control_xfer(rhport, p_request, &tmp, 1); - return false; // Yet not implemented } diff --git a/examples/device/audio_test_freertos/src/plot_audio_samples.py b/examples/device/audio_test_freertos/src/plot_audio_samples.py index 6f1518be5..304b2d5de 100644 --- a/examples/device/audio_test_freertos/src/plot_audio_samples.py +++ b/examples/device/audio_test_freertos/src/plot_audio_samples.py @@ -31,4 +31,3 @@ if __name__ == '__main__': plt.ylabel('Amplitude') plt.title('MicNode') plt.show() - \ No newline at end of file diff --git a/examples/device/cdc_msc_freertos/skip.txt b/examples/device/cdc_msc_freertos/skip.txt index a6f96b288..eb434c23b 100644 --- a/examples/device/cdc_msc_freertos/skip.txt +++ b/examples/device/cdc_msc_freertos/skip.txt @@ -9,5 +9,6 @@ mcu:SAMD11 mcu:SAMX7X mcu:VALENTYUSB_EPTRI mcu:RAXXX +mcu:STM32L0 family:broadcom_32bit family:broadcom_64bit diff --git a/examples/device/video_capture_2ch/skip.txt b/examples/device/video_capture_2ch/skip.txt index b36abf721..15c176a2a 100644 --- a/examples/device/video_capture_2ch/skip.txt +++ b/examples/device/video_capture_2ch/skip.txt @@ -3,6 +3,7 @@ mcu:NUC121 mcu:SAMD11 mcu:GD32VF103 mcu:CH32V307 +mcu:STM32L0 family:espressif board:curiosity_nano board:kuiic diff --git a/hw/bsp/stm32l0/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32l0/FreeRTOSConfig/FreeRTOSConfig.h index 37e7e0943..40146e73a 100644 --- a/hw/bsp/stm32l0/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/stm32l0/FreeRTOSConfig/FreeRTOSConfig.h @@ -44,7 +44,7 @@ // skip if included from IAR assembler #ifndef __IASMARM__ - #include "stm32f0xx.h" + #include "stm32l0xx.h" #endif /* Cortex M23/M33 port configuration. */ -- cgit v1.3.1 From 327e3ec4bd1908e57e2ecd90738f01fc04a17ba1 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 28 Apr 2024 21:59:54 +0200 Subject: Stall unsupported class request. --- src/class/net/ncm_device.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 14ace9d8e..829161865 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -947,7 +947,7 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t } switch (request->bmRequestType_bit.type) { - case TUSB_REQ_TYPE_STANDARD: + case TUSB_REQ_TYPE_STANDARD: { switch (request->bRequest) { case TUSB_REQ_GET_INTERFACE: { TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex, false); @@ -975,14 +975,15 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t default: return false; } - break; + } + break; - case TUSB_REQ_TYPE_CLASS: + case TUSB_REQ_TYPE_CLASS: { TU_VERIFY(ncm_interface.itf_num == request->wIndex, false); - + switch (request->bRequest) { TU_LOG3(" TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); - if (request->bRequest == NCM_GET_NTB_PARAMETERS) { + case NCM_GET_NTB_PARAMETERS: { // transfer NTB parameters to host. // TODO can one assume, that tud_control_xfer() succeeds? TU_LOG3(" NCM_GET_NTB_PARAMETERS\n"); @@ -990,6 +991,13 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t } break; + // unsupported request + default: + return false ; + + } + } + break; // unsupported request default: return false ; -- cgit v1.3.1 From c303b5d81d3dd9d5dc9f831af704e6d40366d7cf Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 29 Apr 2024 22:35:55 +0200 Subject: Guard const addr fifo functions with TUP_MEM_CONST_ADDR. --- src/common/tusb_fifo.c | 31 +++++++++++++++++++++++++++++-- src/common/tusb_fifo.h | 4 ++++ src/common/tusb_mcu.h | 4 ++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 76696396b..8a0fd4417 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -62,7 +62,9 @@ TU_ATTR_ALWAYS_INLINE static inline void _ff_unlock(osal_mutex_t mutex) typedef enum { TU_FIFO_COPY_INC, ///< Copy from/to an increasing source/destination address - default mode +#ifdef TUP_MEM_CONST_ADDR TU_FIFO_COPY_CST_FULL_WORDS, ///< Copy from/to a constant source/destination address - required for e.g. STM32 to write into USB hardware FIFO +#endif } tu_fifo_copy_mode_t; bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable) @@ -92,6 +94,7 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si // Pull & Push //--------------------------------------------------------------------+ +#ifdef TUP_MEM_CONST_ADDR // Intended to be used to read from hardware USB FIFO in e.g. STM32 where all data is read from a constant address // Code adapted from dcd_synopsys.c // TODO generalize with configurable 1 byte or 4 byte each read @@ -140,6 +143,7 @@ static void _ff_pull_const_addr(void * app_buf, const uint8_t * ff_buf, uint16_t *reg_tx = tmp32; } } +#endif // send one item to fifo WITHOUT updating write pointer static inline void _ff_push(tu_fifo_t* f, void const * app_buf, uint16_t rel) @@ -179,7 +183,7 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t memcpy(f->buffer, ((uint8_t const*) app_buf) + lin_bytes, wrap_bytes); } break; - +#ifdef TUP_MEM_CONST_ADDR case TU_FIFO_COPY_CST_FULL_WORDS: // Intended for hardware buffers from which it can be read word by word only if(n <= lin_count) @@ -224,6 +228,7 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t if (wrap_bytes > 0) _ff_push_const_addr(ff_buf, app_buf, wrap_bytes); } break; +#endif default: break; } } @@ -265,7 +270,7 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr, memcpy((uint8_t*) app_buf + lin_bytes, f->buffer, wrap_bytes); } break; - +#ifdef TUP_MEM_CONST_ADDR case TU_FIFO_COPY_CST_FULL_WORDS: if ( n <= lin_count ) { @@ -310,6 +315,7 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr, // Read data wrapped part if (wrap_bytes > 0) _ff_pull_const_addr(app_buf, ff_buf, wrap_bytes); } +#endif break; default: break; @@ -727,10 +733,29 @@ uint16_t tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n) return _tu_fifo_read_n(f, buffer, n, TU_FIFO_COPY_INC); } +#ifdef TUP_MEM_CONST_ADDR +/******************************************************************************/ +/*! + @brief This function will read n elements from the array index specified by + the read pointer and increment the read index. + This function checks for an overflow and corrects read pointer if required. + The dest address will not be incremented which is useful for writing to registers. + + @param[in] f + Pointer to the FIFO buffer to manipulate + @param[in] buffer + The pointer to data location + @param[in] n + Number of element that buffer can afford + + @returns number of items read from the FIFO + */ +/******************************************************************************/ uint16_t tu_fifo_read_n_const_addr_full_words(tu_fifo_t* f, void * buffer, uint16_t n) { return _tu_fifo_read_n(f, buffer, n, TU_FIFO_COPY_CST_FULL_WORDS); } +#endif /******************************************************************************/ /*! @@ -839,6 +864,7 @@ uint16_t tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n) return _tu_fifo_write_n(f, data, n, TU_FIFO_COPY_INC); } +#ifdef TUP_MEM_CONST_ADDR /******************************************************************************/ /*! @brief This function will write n elements into the array index specified by @@ -858,6 +884,7 @@ uint16_t tu_fifo_write_n_const_addr_full_words(tu_fifo_t* f, const void * data, { return _tu_fifo_write_n(f, data, n, TU_FIFO_COPY_CST_FULL_WORDS); } +#endif /******************************************************************************/ /*! diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 2d9f5e667..e50d9afd4 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -156,11 +156,15 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si bool tu_fifo_write (tu_fifo_t* f, void const * p_data); uint16_t tu_fifo_write_n (tu_fifo_t* f, void const * p_data, uint16_t n); +#ifdef TUP_MEM_CONST_ADDR uint16_t tu_fifo_write_n_const_addr_full_words (tu_fifo_t* f, const void * data, uint16_t n); +#endif bool tu_fifo_read (tu_fifo_t* f, void * p_buffer); uint16_t tu_fifo_read_n (tu_fifo_t* f, void * p_buffer, uint16_t n); +#ifdef TUP_MEM_CONST_ADDR uint16_t tu_fifo_read_n_const_addr_full_words (tu_fifo_t* f, void * buffer, uint16_t n); +#endif bool tu_fifo_peek (tu_fifo_t* f, void * p_buffer); uint16_t tu_fifo_peek_n (tu_fifo_t* f, void * p_buffer, uint16_t n); diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 5a567f2d5..c69bc9995 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -448,4 +448,8 @@ #define TUP_DCD_EDPT_ISO_ALLOC #endif +#if defined(TUP_USBIP_DWC2) + #define TUP_MEM_CONST_ADDR +#endif + #endif -- cgit v1.3.1 From 56dbfe59d93975a6256f5bb00da68919b28e07cb Mon Sep 17 00:00:00 2001 From: maflcko <6399679+maflcko@users.noreply.github.com> Date: Tue, 30 Apr 2024 11:00:45 +0200 Subject: Update dnserver.c: Match dnserv_free signature with fwd-decl --- lib/networking/dnserver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/networking/dnserver.c b/lib/networking/dnserver.c index 6d15fee02..25bbf4875 100644 --- a/lib/networking/dnserver.c +++ b/lib/networking/dnserver.c @@ -192,7 +192,7 @@ err_t dnserv_init(const ip_addr_t *bind, uint16_t port, dns_query_proc_t qp) return ERR_OK; } -void dnserv_free() +void dnserv_free(void) { if (pcb == NULL) return; udp_remove(pcb); -- cgit v1.3.1 From 35e7fddc733c9abb7a6d6aae21994ca8bf053581 Mon Sep 17 00:00:00 2001 From: Trevor <4226647+trejan@users.noreply.github.com> Date: Tue, 30 Apr 2024 16:53:25 +0100 Subject: Add missing capability bit for CDC ACM serial break support The send break capability bit is needed for serial break support with Linux and possibly MacOS hosts. [A recent Linux kernel patch made it check the ACM capability bits before sending a serial break](https://github.com/raspberrypi/linux/commit/19e321c3eedd4c681a49f532a196bead5d57205e). --- src/device/usbd.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/usbd.h b/src/device/usbd.h index 0197628e2..f36734040 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -221,8 +221,8 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0120),\ /* CDC Call */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_CALL_MANAGEMENT, 0, (uint8_t)((_itfnum) + 1),\ - /* CDC ACM: support line request */\ - 4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 2,\ + /* CDC ACM: support line request + send break */\ + 4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 6,\ /* CDC Union */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\ /* Endpoint Notification */\ -- cgit v1.3.1 From ea3f1d39e8bfc82facc7b3e503d7c71f9119de2b Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 May 2024 13:29:29 +0700 Subject: add cmake for pi zero (renamed from pi zero_w), build but the flash size seem wrong (only 24 bytes for text) --- .clang-format | 6 -- examples/build_system/cmake/cpu/arm1176jzf-s.cmake | 19 ++++ examples/build_system/make/cpu/arm1176.mk | 9 -- examples/build_system/make/cpu/arm1176jzf-s.mk | 9 ++ .../boards/raspberrypi_zero/board.cmake | 8 ++ .../broadcom_32bit/boards/raspberrypi_zero/board.h | 38 ++++++++ .../boards/raspberrypi_zero/board.mk | 5 + .../boards/raspberrypi_zero_w/board.h | 38 -------- .../boards/raspberrypi_zero_w/board.mk | 5 - hw/bsp/broadcom_32bit/family.c | 11 +++ hw/bsp/broadcom_32bit/family.cmake | 107 +++++++++++++++++++++ hw/bsp/broadcom_32bit/family.mk | 5 +- src/common/tusb_fifo.h | 12 +-- src/common/tusb_mcu.h | 2 +- src/common/tusb_verify.h | 3 +- 15 files changed, 206 insertions(+), 71 deletions(-) delete mode 100644 .clang-format create mode 100644 examples/build_system/cmake/cpu/arm1176jzf-s.cmake delete mode 100644 examples/build_system/make/cpu/arm1176.mk create mode 100644 examples/build_system/make/cpu/arm1176jzf-s.mk create mode 100644 hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.cmake create mode 100644 hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.h create mode 100644 hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.mk delete mode 100644 hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.h delete mode 100644 hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk create mode 100644 hw/bsp/broadcom_32bit/family.cmake diff --git a/.clang-format b/.clang-format deleted file mode 100644 index 4369c29fe..000000000 --- a/.clang-format +++ /dev/null @@ -1,6 +0,0 @@ ---- -BreakBeforeBraces: Linux -ColumnLimit: '200' -ReflowComments: 'true' - -... diff --git a/examples/build_system/cmake/cpu/arm1176jzf-s.cmake b/examples/build_system/cmake/cpu/arm1176jzf-s.cmake new file mode 100644 index 000000000..11bb52f30 --- /dev/null +++ b/examples/build_system/cmake/cpu/arm1176jzf-s.cmake @@ -0,0 +1,19 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mcpu=arm1176jzf-s + ) + # set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=arm1176jzf-s + -mfpu=none + -mfloat-abi=soft + ) + #set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + message(FATAL_ERROR "IAR not supported") + +endif () diff --git a/examples/build_system/make/cpu/arm1176.mk b/examples/build_system/make/cpu/arm1176.mk deleted file mode 100644 index 022ccf7ad..000000000 --- a/examples/build_system/make/cpu/arm1176.mk +++ /dev/null @@ -1,9 +0,0 @@ -ifeq ($(TOOLCHAIN),gcc) - CFLAGS += \ - -mcpu=arm1176jzf-s \ - -else ifeq ($(TOOLCHAIN),iar) - #CFLAGS += --cpu cortex-a53 - #ASFLAGS += --cpu cortex-a53 - -endif diff --git a/examples/build_system/make/cpu/arm1176jzf-s.mk b/examples/build_system/make/cpu/arm1176jzf-s.mk new file mode 100644 index 000000000..022ccf7ad --- /dev/null +++ b/examples/build_system/make/cpu/arm1176jzf-s.mk @@ -0,0 +1,9 @@ +ifeq ($(TOOLCHAIN),gcc) + CFLAGS += \ + -mcpu=arm1176jzf-s \ + +else ifeq ($(TOOLCHAIN),iar) + #CFLAGS += --cpu cortex-a53 + #ASFLAGS += --cpu cortex-a53 + +endif diff --git a/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.cmake b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.cmake new file mode 100644 index 000000000..2b8cc19e0 --- /dev/null +++ b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.cmake @@ -0,0 +1,8 @@ +set(CMAKE_SYSTEM_PROCESSOR arm1176jzf-s CACHE INTERNAL "System Processor") +#set(SUFFIX "") + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + BCM_VERSION=2835 + ) +endfunction() diff --git a/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.h b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.h new file mode 100644 index 000000000..84a106346 --- /dev/null +++ b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.h @@ -0,0 +1,38 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.mk b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.mk new file mode 100644 index 000000000..7a248ed24 --- /dev/null +++ b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.mk @@ -0,0 +1,5 @@ +CPU_CORE = arm1176jzf-s +CFLAGS += -DBCM_VERSION=2835 \ + -DCFG_TUSB_MCU=OPT_MCU_BCM2835 + +SUFFIX = diff --git a/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.h b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.h deleted file mode 100644 index 84a106346..000000000 --- a/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#ifdef __cplusplus - } -#endif - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk deleted file mode 100644 index 052033230..000000000 --- a/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk +++ /dev/null @@ -1,5 +0,0 @@ -CPU_CORE = arm1176 -CFLAGS += -DBCM_VERSION=2835 \ - -DCFG_TUSB_MCU=OPT_MCU_BCM2835 - -SUFFIX = diff --git a/hw/bsp/broadcom_32bit/family.c b/hw/bsp/broadcom_32bit/family.c index 664b4dcaf..626565e34 100644 --- a/hw/bsp/broadcom_32bit/family.c +++ b/hw/bsp/broadcom_32bit/family.c @@ -27,6 +27,13 @@ #include "bsp/board_api.h" #include "board.h" +// Suppress warning caused by mcu driver +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif + #include "broadcom/cpu.h" #include "broadcom/gpio.h" #include "broadcom/interrupts.h" @@ -34,6 +41,10 @@ #include "broadcom/caches.h" #include "broadcom/vcmailbox.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + // LED #define LED_PIN 18 #define LED_STATE_ON 1 diff --git a/hw/bsp/broadcom_32bit/family.cmake b/hw/bsp/broadcom_32bit/family.cmake new file mode 100644 index 000000000..223c85e48 --- /dev/null +++ b/hw/bsp/broadcom_32bit/family.cmake @@ -0,0 +1,107 @@ +include_guard() + +set(MCU_DIR ${TOP}/hw/mcu/broadcom) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS BCM2835 CACHE INTERNAL "") + + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${MCU_DIR}/broadcom/link.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) + set(STARTUP_FILE_GNU ${MCU_DIR}/broadcom/boot.s) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${MCU_DIR}/broadcom/gen/interrupt_handlers.c + ${MCU_DIR}/broadcom/gpio.c + ${MCU_DIR}/broadcom/interrupts.c + ${MCU_DIR}/broadcom/mmu.c + ${MCU_DIR}/broadcom/caches.c + ${MCU_DIR}/broadcom/vcmailbox.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_compile_options(${BOARD_TARGET} PUBLIC + -O0 + -ffreestanding + -mgeneral-regs-only + -fno-exceptions + -std=c17 + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${MCU_DIR} + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostdlib -nostartfiles + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_BCM2835 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/broadcom_32bit/family.mk b/hw/bsp/broadcom_32bit/family.mk index cf68e21ee..e15bd93f7 100644 --- a/hw/bsp/broadcom_32bit/family.mk +++ b/hw/bsp/broadcom_32bit/family.mk @@ -1,5 +1,4 @@ MCU_DIR = hw/mcu/broadcom -DEPS_SUBMODULES += $(MCU_DIR) include $(TOP)/$(BOARD_PATH)/board.mk @@ -27,15 +26,13 @@ SRC_C += \ $(MCU_DIR)/broadcom/caches.c \ $(MCU_DIR)/broadcom/vcmailbox.c -SKIP_NANOLIB = 1 - LD_FILE = $(MCU_DIR)/broadcom/link$(SUFFIX).ld INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(MCU_DIR) -SRC_S += $(MCU_DIR)/broadcom/boot$(SUFFIX).S +SRC_S += $(MCU_DIR)/broadcom/boot$(SUFFIX).s $(BUILD)/kernel$(SUFFIX).img: $(BUILD)/$(PROJECT).elf $(OBJCOPY) -O binary $^ $@ diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 2d9f5e667..0de576601 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -145,13 +145,13 @@ bool tu_fifo_clear(tu_fifo_t *f); bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable); #if OSAL_MUTEX_REQUIRED - TU_ATTR_ALWAYS_INLINE static inline - void tu_fifo_config_mutex(tu_fifo_t *f, osal_mutex_t wr_mutex, osal_mutex_t rd_mutex) { - f->mutex_wr = wr_mutex; - f->mutex_rd = rd_mutex; - } +TU_ATTR_ALWAYS_INLINE static inline +void tu_fifo_config_mutex(tu_fifo_t *f, osal_mutex_t wr_mutex, osal_mutex_t rd_mutex) { + f->mutex_wr = wr_mutex; + f->mutex_rd = rd_mutex; +} #else - #define tu_fifo_config_mutex(_f, _wr_mutex, _rd_mutex) +#define tu_fifo_config_mutex(_f, _wr_mutex, _rd_mutex) #endif bool tu_fifo_write (tu_fifo_t* f, void const * p_data); diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 5a567f2d5..8d58be2a1 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -430,7 +430,7 @@ #endif #if !defined(TUP_DCD_ENDPOINT_MAX) && defined(CFG_TUD_ENABLED) && CFG_TUD_ENABLED -#warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" + #warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" #define TUP_DCD_ENDPOINT_MAX 8 #endif diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index 0a9549c99..dde0550d3 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -78,8 +78,7 @@ // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33. M55 #if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__) || \ defined(__ARM7M__) || defined (__ARM7EM__) || defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) - #define TU_BREAKPOINT() do \ - { \ + #define TU_BREAKPOINT() do { \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ if ( (*ARM_CM_DHCSR) & 1UL ) __asm("BKPT #0\n"); /* Only halt mcu if debugger is attached */ \ } while(0) -- cgit v1.3.1 From 980f5992c8bc9b66e13cd409ae782a588053ec3e Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 May 2024 16:57:50 +0700 Subject: add cmake for broadcom 64-bit, like 32-bit it compiles but text is only 8 bytes (incorrect) --- examples/build_system/cmake/cpu/cortex-a53.cmake | 17 ++++ examples/build_system/cmake/cpu/cortex-a72.cmake | 17 ++++ .../build_system/cmake/toolchain/aarch64_gcc.cmake | 21 ++++ .../boards/raspberrypi_cm4/board.cmake | 5 + .../boards/raspberrypi_zero2/board.cmake | 5 + .../boards/raspberrypi_zero2/board.h | 38 +++++++ .../boards/raspberrypi_zero2/board.mk | 3 + .../boards/raspberrypi_zero2w/board.h | 38 ------- .../boards/raspberrypi_zero2w/board.mk | 3 - hw/bsp/broadcom_64bit/family.c | 11 +++ hw/bsp/broadcom_64bit/family.cmake | 110 +++++++++++++++++++++ hw/bsp/broadcom_64bit/family.mk | 6 +- 12 files changed, 228 insertions(+), 46 deletions(-) create mode 100644 examples/build_system/cmake/cpu/cortex-a53.cmake create mode 100644 examples/build_system/cmake/cpu/cortex-a72.cmake create mode 100644 examples/build_system/cmake/toolchain/aarch64_gcc.cmake create mode 100644 hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.cmake create mode 100644 hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.cmake create mode 100644 hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.h create mode 100644 hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.mk delete mode 100644 hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.h delete mode 100644 hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.mk create mode 100644 hw/bsp/broadcom_64bit/family.cmake diff --git a/examples/build_system/cmake/cpu/cortex-a53.cmake b/examples/build_system/cmake/cpu/cortex-a53.cmake new file mode 100644 index 000000000..dde8c0a0c --- /dev/null +++ b/examples/build_system/cmake/cpu/cortex-a53.cmake @@ -0,0 +1,17 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mcpu=cortex-a53 + ) + # set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-a53 + ) + #set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + message(FATAL_ERROR "IAR not supported") + +endif () diff --git a/examples/build_system/cmake/cpu/cortex-a72.cmake b/examples/build_system/cmake/cpu/cortex-a72.cmake new file mode 100644 index 000000000..a44324234 --- /dev/null +++ b/examples/build_system/cmake/cpu/cortex-a72.cmake @@ -0,0 +1,17 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mcpu=cortex-a72 + ) + # set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-a72 + ) + #set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + message(FATAL_ERROR "IAR not supported") + +endif () diff --git a/examples/build_system/cmake/toolchain/aarch64_gcc.cmake b/examples/build_system/cmake/toolchain/aarch64_gcc.cmake new file mode 100644 index 000000000..2d30a0b71 --- /dev/null +++ b/examples/build_system/cmake/toolchain/aarch64_gcc.cmake @@ -0,0 +1,21 @@ +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER "aarch64-none-elf-gcc") +endif () + +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER "aarch64-none-elf-g++") +endif () + +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +set(CMAKE_SIZE "aarch64-none-elf-size" CACHE FILEPATH "") +set(CMAKE_OBJCOPY "aarch64-none-elf-objcopy" CACHE FILEPATH "") +set(CMAKE_OBJDUMP "aarch64-none-elf-objdump" CACHE FILEPATH "") + +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) + +get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) +if (IS_IN_TRY_COMPILE) + set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") + set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") + cmake_print_variables(CMAKE_C_LINK_FLAGS) +endif () diff --git a/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.cmake b/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.cmake new file mode 100644 index 000000000..919068f1d --- /dev/null +++ b/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.cmake @@ -0,0 +1,5 @@ +set(CMAKE_SYSTEM_PROCESSOR cortex-a72 CACHE INTERNAL "System Processor") +set(BCM_VERSION 2711) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.cmake b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.cmake new file mode 100644 index 000000000..85f84e947 --- /dev/null +++ b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.cmake @@ -0,0 +1,5 @@ +set(CMAKE_SYSTEM_PROCESSOR cortex-a53 CACHE INTERNAL "System Processor") +set(BCM_VERSION 2837) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.h b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.h new file mode 100644 index 000000000..84a106346 --- /dev/null +++ b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.h @@ -0,0 +1,38 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.mk b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.mk new file mode 100644 index 000000000..da3fe17bc --- /dev/null +++ b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.mk @@ -0,0 +1,3 @@ +CPU_CORE = cortex-a53 +CFLAGS += -DBCM_VERSION=2837 \ + -DCFG_TUSB_MCU=OPT_MCU_BCM2837 diff --git a/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.h b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.h deleted file mode 100644 index 84a106346..000000000 --- a/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#ifdef __cplusplus - } -#endif - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.mk b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.mk deleted file mode 100644 index da3fe17bc..000000000 --- a/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.mk +++ /dev/null @@ -1,3 +0,0 @@ -CPU_CORE = cortex-a53 -CFLAGS += -DBCM_VERSION=2837 \ - -DCFG_TUSB_MCU=OPT_MCU_BCM2837 diff --git a/hw/bsp/broadcom_64bit/family.c b/hw/bsp/broadcom_64bit/family.c index 664b4dcaf..626565e34 100644 --- a/hw/bsp/broadcom_64bit/family.c +++ b/hw/bsp/broadcom_64bit/family.c @@ -27,6 +27,13 @@ #include "bsp/board_api.h" #include "board.h" +// Suppress warning caused by mcu driver +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif + #include "broadcom/cpu.h" #include "broadcom/gpio.h" #include "broadcom/interrupts.h" @@ -34,6 +41,10 @@ #include "broadcom/caches.h" #include "broadcom/vcmailbox.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + // LED #define LED_PIN 18 #define LED_STATE_ON 1 diff --git a/hw/bsp/broadcom_64bit/family.cmake b/hw/bsp/broadcom_64bit/family.cmake new file mode 100644 index 000000000..b534e29be --- /dev/null +++ b/hw/bsp/broadcom_64bit/family.cmake @@ -0,0 +1,110 @@ +include_guard() + +set(MCU_DIR ${TOP}/hw/mcu/broadcom) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/aarch64_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS BCM2711 BCM2835 CACHE INTERNAL "") + + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${MCU_DIR}/broadcom/link8.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) + set(STARTUP_FILE_GNU ${MCU_DIR}/broadcom/boot8.s) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${MCU_DIR}/broadcom/gen/interrupt_handlers.c + ${MCU_DIR}/broadcom/gpio.c + ${MCU_DIR}/broadcom/interrupts.c + ${MCU_DIR}/broadcom/mmu.c + ${MCU_DIR}/broadcom/caches.c + ${MCU_DIR}/broadcom/vcmailbox.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_compile_options(${BOARD_TARGET} PUBLIC + -O0 + -ffreestanding + -mgeneral-regs-only + -fno-exceptions + -std=c17 + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + BCM_VERSION=${BCM_VERSION} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${MCU_DIR} + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostdlib -nostartfiles + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_BCM${BCM_VERSION} ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/broadcom_64bit/family.mk b/hw/bsp/broadcom_64bit/family.mk index 97af6d64a..80eff1d36 100644 --- a/hw/bsp/broadcom_64bit/family.mk +++ b/hw/bsp/broadcom_64bit/family.mk @@ -1,6 +1,4 @@ MCU_DIR = hw/mcu/broadcom -DEPS_SUBMODULES += $(MCU_DIR) - include $(TOP)/$(BOARD_PATH)/board.mk CFLAGS += \ @@ -26,8 +24,6 @@ SRC_C += \ $(MCU_DIR)/broadcom/caches.c \ $(MCU_DIR)/broadcom/vcmailbox.c -SKIP_NANOLIB = 1 - LD_FILE = $(MCU_DIR)/broadcom/link8.ld INC += \ @@ -35,7 +31,7 @@ INC += \ $(TOP)/$(MCU_DIR) \ $(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include -SRC_S += $(MCU_DIR)/broadcom/boot8.S +SRC_S += $(MCU_DIR)/broadcom/boot8.s $(BUILD)/kernel8.img: $(BUILD)/$(PROJECT).elf $(OBJCOPY) -O binary $^ $@ -- cgit v1.3.1 From 4b537a4f8c96519a3e77a63ff8ddbb3c528bd857 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 May 2024 16:58:43 +0700 Subject: add cmake for kinetis k32l2 family --- .../kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h | 169 ++++++++++++++++ .../kinetis_k32l2/boards/frdm_k32l2a4s/board.cmake | 15 ++ hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.h | 34 ++++ .../boards/frdm_k32l2a4s/clock_config.c | 2 +- .../boards/frdm_k32l2a4s/frdm_k32l2a4s.c | 171 ---------------- .../kinetis_k32l2/boards/frdm_k32l2b/board.cmake | 15 ++ hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.h | 22 +++ .../boards/frdm_k32l2b/clock_config.c | 2 +- .../kinetis_k32l2/boards/frdm_k32l2b/frdm_k32l2b.c | 140 ------------- .../boards/kuiic/K32L2B31xxxxA_flash.ld | 216 --------------------- hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake | 15 ++ hw/bsp/kinetis_k32l2/boards/kuiic/board.h | 20 ++ hw/bsp/kinetis_k32l2/boards/kuiic/board.mk | 2 +- hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c | 39 ++++ hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h | 14 ++ hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.c | 203 ------------------- hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld | 216 +++++++++++++++++++++ hw/bsp/kinetis_k32l2/family.c | 170 ++++++++++++++++ hw/bsp/kinetis_k32l2/family.cmake | 112 +++++++++++ hw/bsp/kinetis_k32l2/family.mk | 9 +- 20 files changed, 849 insertions(+), 737 deletions(-) create mode 100644 hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.cmake delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/frdm_k32l2a4s.c create mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.cmake delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/frdm_k32l2b.c delete mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/K32L2B31xxxxA_flash.ld create mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake create mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c create mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.c create mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld create mode 100644 hw/bsp/kinetis_k32l2/family.c create mode 100644 hw/bsp/kinetis_k32l2/family.cmake diff --git a/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..133728596 --- /dev/null +++ b/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,169 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "fsl_device_registers.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 2 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* Define to trap errors during development. */ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) + #define configASSERT(_exp) \ + do {\ + if ( !(_exp) ) { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ + taskDISABLE_INTERRUPTS(); \ + __asm("BKPT #0\n"); \ + }\ + }\ + } while(0) +#else + #define configASSERT( x ) +#endif + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 4 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<SOPT5 = ((SIM->SOPT5 & + /* Mask bits to zero which are setting */ + (~(SIM_SOPT5_LPUART0TXSRC_MASK | SIM_SOPT5_LPUART0RXSRC_MASK))) + /* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */ + | SIM_SOPT5_LPUART0TXSRC(SOPT5_LPUART0TXSRC_LPUART_TX) + /* LPUART0 Receive Data Source Select: LPUART_RX pin. */ + | SIM_SOPT5_LPUART0RXSRC(SOPT5_LPUART0RXSRC_LPUART_RX)); + + BOARD_BootClockRUN(); + SystemCoreClockUpdate(); + CLOCK_SetLpuart0Clock(1); +} #endif /* BOARD_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c index e74000827..86eb42ef8 100644 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c @@ -48,7 +48,7 @@ board: FRDM-K32L2B * Variables ******************************************************************************/ /* System clock frequency. */ -extern uint32_t SystemCoreClock; +//extern uint32_t SystemCoreClock; /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/frdm_k32l2b.c b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/frdm_k32l2b.c deleted file mode 100644 index 3f99b0cbd..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/frdm_k32l2b.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2018, hathach (tinyusb.org) - * Copyright (c) 2020, Koji Kitayama - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "bsp/board_api.h" -#include "board.h" -#include "fsl_gpio.h" -#include "fsl_port.h" -#include "fsl_clock.h" -#include "fsl_lpuart.h" - -#include "clock_config.h" - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB0_IRQHandler(void) -{ - tud_int_handler(0); -} - -void board_init(void) -{ - /* Enable port clocks for UART/LED/Button pins */ - CLOCK_EnableClock(UART_PIN_CLOCK); - CLOCK_EnableClock(LED_PIN_CLOCK); - CLOCK_EnableClock(BUTTON_PIN_CLOCK); - - gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0 }; - GPIO_PinInit(LED_GPIO, LED_PIN, &led_config); - PORT_SetPinMux(LED_PORT, LED_PIN, kPORT_MuxAsGpio); - - gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 }; - GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); - const port_pin_config_t BUTTON_CFG = { - kPORT_PullUp, - kPORT_FastSlewRate, - kPORT_PassiveFilterDisable, - kPORT_LowDriveStrength, - kPORT_MuxAsGpio - }; - PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG); - - /* PORTA1 (pin 23) is configured as LPUART0_RX */ - PORT_SetPinMux(PORTA, 1U, kPORT_MuxAlt2); - /* PORTA2 (pin 24) is configured as LPUART0_TX */ - PORT_SetPinMux(PORTA, 2U, kPORT_MuxAlt2); - - SIM->SOPT5 = ((SIM->SOPT5 & - /* Mask bits to zero which are setting */ - (~(SIM_SOPT5_LPUART0TXSRC_MASK | SIM_SOPT5_LPUART0RXSRC_MASK))) - /* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */ - | SIM_SOPT5_LPUART0TXSRC(SOPT5_LPUART0TXSRC_LPUART_TX) - /* LPUART0 Receive Data Source Select: LPUART_RX pin. */ - | SIM_SOPT5_LPUART0RXSRC(SOPT5_LPUART0RXSRC_LPUART_RX)); - - BOARD_BootClockRUN(); - SystemCoreClockUpdate(); - CLOCK_SetLpuart0Clock(1); - -#if CFG_TUSB_OS == OPT_OS_NONE - // 1ms tick timer - SysTick_Config(SystemCoreClock / 1000); -#elif CFG_TUSB_OS == OPT_OS_FREERTOS - // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); -#endif - - lpuart_config_t uart_config; - LPUART_GetDefaultConfig(&uart_config); - uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; - uart_config.enableTx = true; - uart_config.enableRx = true; - LPUART_Init(UART_PORT, &uart_config, CLOCK_GetFreq(kCLOCK_McgIrc48MClk)); - - // USB - CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U); -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) -{ - GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); -} - -uint32_t board_button_read(void) -{ - return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); -} - -int board_uart_read(uint8_t* buf, int len) -{ - LPUART_ReadBlocking(UART_PORT, buf, len); - return len; -} - -int board_uart_write(void const * buf, int len) -{ - LPUART_WriteBlocking(UART_PORT, (uint8_t const*) buf, len); - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; -void SysTick_Handler(void) -{ - system_ticks++; -} - -uint32_t board_millis(void) -{ - return system_ticks; -} -#endif diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/K32L2B31xxxxA_flash.ld b/hw/bsp/kinetis_k32l2/boards/kuiic/K32L2B31xxxxA_flash.ld deleted file mode 100644 index f478a99c7..000000000 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/K32L2B31xxxxA_flash.ld +++ /dev/null @@ -1,216 +0,0 @@ -/* -** ################################################################### -** Processors: K32L2B31VFM0A -** K32L2B31VFT0A -** K32L2B31VLH0A -** K32L2B31VMP0A -** -** Compiler: GNU C Compiler -** Reference manual: K32L2B3xRM, Rev.0, July 2019 -** Version: rev. 1.0, 2019-07-30 -** Build: b190930 -** -** Abstract: -** Linker file for the GNU C Compiler -** -** Copyright 2016 Freescale Semiconductor, Inc. -** Copyright 2016-2019 NXP -** All rights reserved. -** -** SPDX-License-Identifier: BSD-3-Clause -** -** http: www.nxp.com -** mail: support@nxp.com -** -** ################################################################### -*/ - -/* Entry Point */ -ENTRY(Reset_Handler) - -HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; - -/* Specify the memory areas */ -MEMORY -{ - m_interrupts (RX) : ORIGIN = 0x00008000, LENGTH = 0x00000200 - m_flash_config (RX) : ORIGIN = 0x00008400, LENGTH = 0x00000010 - m_text (RX) : ORIGIN = 0x00008410, LENGTH = 0x00037BF0 - m_data (RW) : ORIGIN = 0x1FFFE000, LENGTH = 0x00008000 -} - -/* Define output sections */ -SECTIONS -{ - /* The startup code goes first into internal flash */ - .interrupts : - { - . = ALIGN(4); - KEEP(*(.isr_vector)) /* Startup code */ - . = ALIGN(4); - } > m_interrupts - - .flash_config : - { - . = ALIGN(4); - KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */ - . = ALIGN(4); - } > m_flash_config - - /* The program code and other data goes into internal flash */ - .text : - { - . = ALIGN(4); - *(.text) /* .text sections (code) */ - *(.text*) /* .text* sections (code) */ - *(.rodata) /* .rodata sections (constants, strings, etc.) */ - *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ - *(.glue_7) /* glue arm to thumb code */ - *(.glue_7t) /* glue thumb to arm code */ - *(.eh_frame) - KEEP (*(.init)) - KEEP (*(.fini)) - . = ALIGN(4); - } > m_text - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > m_text - - .ARM : - { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } > m_text - - .ctors : - { - __CTOR_LIST__ = .; - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP (*crtbegin.o(.ctors)) - KEEP (*crtbegin?.o(.ctors)) - /* We don't want to include the .ctor section from - from the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __CTOR_END__ = .; - } > m_text - - .dtors : - { - __DTOR_LIST__ = .; - KEEP (*crtbegin.o(.dtors)) - KEEP (*crtbegin?.o(.dtors)) - KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - __DTOR_END__ = .; - } > m_text - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array*)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } > m_text - - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array*)) - PROVIDE_HIDDEN (__init_array_end = .); - } > m_text - - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT(.fini_array.*))) - KEEP (*(.fini_array*)) - PROVIDE_HIDDEN (__fini_array_end = .); - } > m_text - - __etext = .; /* define a global symbol at end of code */ - __DATA_ROM = .; /* Symbol is used by startup for data initialization */ - - /* reserve MTB memory at the beginning of m_data */ - .mtb : /* MTB buffer address as defined by the hardware */ - { - . = ALIGN(8); - _mtb_start = .; - KEEP(*(.mtb_buf)) /* need to KEEP Micro Trace Buffer as not referenced by application */ - . = ALIGN(8); - _mtb_end = .; - } > m_data - - .data : AT(__DATA_ROM) - { - . = ALIGN(4); - __DATA_RAM = .; - __data_start__ = .; /* create a global symbol at data start */ - *(.data) /* .data sections */ - *(.data*) /* .data* sections */ - KEEP(*(.jcr*)) - . = ALIGN(4); - __data_end__ = .; /* define a global symbol at data end */ - } > m_data - - __DATA_END = __DATA_ROM + (__data_end__ - __data_start__); - text_end = ORIGIN(m_text) + LENGTH(m_text); - ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") - - /* Uninitialized data section */ - .bss : - { - /* This is used by the startup in order to initialize the .bss section */ - . = ALIGN(4); - __START_BSS = .; - __bss_start__ = .; - *(.bss) - *(.bss*) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - __END_BSS = .; - } > m_data - - .heap : - { - . = ALIGN(8); - __end__ = .; - PROVIDE(end = .); - __HeapBase = .; - . += HEAP_SIZE; - __HeapLimit = .; - __heap_limit = .; /* Add for _sbrk */ - } > m_data - - .stack : - { - . = ALIGN(8); - . += STACK_SIZE; - } > m_data - - /* Initializes stack on the end of block */ - __StackTop = ORIGIN(m_data) + LENGTH(m_data); - __StackLimit = __StackTop - STACK_SIZE; - PROVIDE(__stack = __StackTop); - - .ARM.attributes 0 : { *(.ARM.attributes) } - - ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap") -} diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake b/hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake new file mode 100644 index 000000000..cf14000ac --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake @@ -0,0 +1,15 @@ +set(MCU_VARIANT K32L2B31A) + +set(JLINK_DEVICE K32L2B31xxxxA) +set(PYOCD_TARGET K32L2B) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/kuiic.ld) + +function(update_board TARGET) + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c + ) + target_compile_definitions(${TARGET} PUBLIC + CPU_K32L2B31VLH0A + ) +endfunction() diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/board.h b/hw/bsp/kinetis_k32l2/boards/kuiic/board.h index 1e2d4f18b..ec3702376 100644 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/board.h +++ b/hw/bsp/kinetis_k32l2/boards/kuiic/board.h @@ -30,6 +30,8 @@ #include "fsl_device_registers.h" +#define USB_CLOCK_SOURCE kCLOCK_UsbSrcIrc48M + // LED #define LED_PIN_CLOCK kCLOCK_PortA #define LED_GPIO GPIOA @@ -42,4 +44,22 @@ #define UART_PIN_RX 3u #define UART_PIN_TX 0u +#define UART_CLOCK_SOURCE_HZ CLOCK_GetFreq(kCLOCK_McgIrc48MClk) + +static inline void BOARD_InitBootPins(void) { + /* PORTC3 is configured as LPUART0_RX */ + PORT_SetPinMux(PORTC, 3U, kPORT_MuxAlt3); + /* PORTA2 (pin 24) is configured as LPUART0_TX */ + PORT_SetPinMux(PORTE, 0U, kPORT_MuxAlt3); + + SIM->SOPT5 = ((SIM->SOPT5 & + /* Mask bits to zero which are setting */ + (~(SIM_SOPT5_LPUART1TXSRC_MASK | SIM_SOPT5_LPUART1RXSRC_MASK))) + /* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */ + | SIM_SOPT5_LPUART1TXSRC(SOPT5_LPUART1TXSRC_LPUART_TX) + /* LPUART0 Receive Data Source Select: LPUART_RX pin. */ + | SIM_SOPT5_LPUART1RXSRC(SOPT5_LPUART1RXSRC_LPUART_RX)); + CLOCK_SetLpuart1Clock(1); +} + #endif /* BOARD_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/board.mk b/hw/bsp/kinetis_k32l2/boards/kuiic/board.mk index fc5bdeec8..2bc5b1e34 100644 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/board.mk +++ b/hw/bsp/kinetis_k32l2/boards/kuiic/board.mk @@ -6,7 +6,7 @@ CFLAGS += -DCPU_K32L2B31VLH0A CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls # All source paths should be relative to the top level. -LD_FILE = $(BOARD_PATH)/K32L2B31xxxxA_flash.ld +LD_FILE = $(BOARD_PATH)/kuiic.ld # For flash-jlink target JLINK_DEVICE = K32L2B31xxxxA diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c b/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c new file mode 100644 index 000000000..c1a6d1a8d --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c @@ -0,0 +1,39 @@ +#include "clock_config.h" +#include "fsl_clock.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +// extern uint32_t SystemCoreClock; + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN = { + .outSrc = kMCGLITE_ClkSrcHirc, /* MCGOUTCLK source is HIRC */ + .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ + .ircs = kMCGLITE_Lirc8M, /* Slow internal reference (LIRC) 8 MHz clock selected */ + .fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */ + .lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */ + .hircEnableInNotHircMode = true, /* HIRC source is enabled */ +}; +const sim_clock_config_t simConfig_BOARD_BootClockRUN = { + .er32kSrc = SIM_OSC32KSEL_LPO_CLK, /* OSC32KSEL select: LPO clock */ + .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ +}; + +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Set MCG to HIRC mode. */ + CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockRUN); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; +} diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h b/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h new file mode 100644 index 000000000..920cad98f --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h @@ -0,0 +1,14 @@ +#ifndef CLOCK_CONFIG_H +#define CLOCK_CONFIG_H + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define SIM_OSC32KSEL_LPO_CLK 3U /*!< OSC32KSEL select: LPO clock */ +#define SOPT5_LPUART1RXSRC_LPUART_RX 0x00u /*!<@brief LPUART1 Receive Data Source Select: LPUART_RX pin */ +#define SOPT5_LPUART1TXSRC_LPUART_TX 0x00u /*!<@brief LPUART1 Transmit Data Source Select: LPUART_TX pin */ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ + +void BOARD_BootClockRUN(void); + +#endif diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.c b/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.c deleted file mode 100644 index b83d5c820..000000000 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2018, hathach (tinyusb.org) - * Copyright (c) 2020, Koji Kitayama - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "bsp/board_api.h" -#include "board.h" -#include "fsl_smc.h" -#include "fsl_gpio.h" -#include "fsl_port.h" -#include "fsl_clock.h" -#include "fsl_lpuart.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ -#define SIM_OSC32KSEL_LPO_CLK 3U /*!< OSC32KSEL select: LPO clock */ -#define SOPT5_LPUART1RXSRC_LPUART_RX 0x00u /*!<@brief LPUART1 Receive Data Source Select: LPUART_RX pin */ -#define SOPT5_LPUART1TXSRC_LPUART_TX 0x00u /*!<@brief LPUART1 Transmit Data Source Select: LPUART_TX pin */ -#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ - -/******************************************************************************* - * Variables - ******************************************************************************/ -/* System clock frequency. */ -// extern uint32_t SystemCoreClock; - -/******************************************************************************* - * Variables for BOARD_BootClockRUN configuration - ******************************************************************************/ -const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN = { - .outSrc = kMCGLITE_ClkSrcHirc, /* MCGOUTCLK source is HIRC */ - .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ - .ircs = kMCGLITE_Lirc8M, /* Slow internal reference (LIRC) 8 MHz clock selected */ - .fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */ - .lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */ - .hircEnableInNotHircMode = true, /* HIRC source is enabled */ -}; -const sim_clock_config_t simConfig_BOARD_BootClockRUN = { - .er32kSrc = SIM_OSC32KSEL_LPO_CLK, /* OSC32KSEL select: LPO clock */ - .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ -}; - -/******************************************************************************* - * Code for BOARD_BootClockRUN configuration - ******************************************************************************/ -void BOARD_BootClockRUN(void) -{ - /* Set the system clock dividers in SIM to safe value. */ - CLOCK_SetSimSafeDivs(); - /* Set MCG to HIRC mode. */ - CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockRUN); - /* Set the clock configuration in SIM module. */ - CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; -} - - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB0_IRQHandler(void) -{ - tud_int_handler(0); -} - -void board_init(void) -{ - /* Enable port clocks for GPIO pins */ - CLOCK_EnableClock(kCLOCK_PortA); - CLOCK_EnableClock(kCLOCK_PortB); - CLOCK_EnableClock(kCLOCK_PortC); - CLOCK_EnableClock(kCLOCK_PortD); - CLOCK_EnableClock(kCLOCK_PortE); - - - gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 1 }; - GPIO_PinInit(GPIOA, 1U, &led_config); - PORT_SetPinMux(PORTA, 1U, kPORT_MuxAsGpio); - led_config.outputLogic = 0; - GPIO_PinInit(GPIOA, 2U, &led_config); - PORT_SetPinMux(PORTA, 2U, kPORT_MuxAsGpio); - -#ifdef BUTTON_PIN - gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 }; - GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); - const port_pin_config_t BUTTON_CFG = { - kPORT_PullUp, - kPORT_FastSlewRate, - kPORT_PassiveFilterDisable, - kPORT_LowDriveStrength, - kPORT_MuxAsGpio - }; - PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG); -#endif - - /* PORTC3 is configured as LPUART0_RX */ - PORT_SetPinMux(PORTC, 3U, kPORT_MuxAlt3); - /* PORTA2 (pin 24) is configured as LPUART0_TX */ - PORT_SetPinMux(PORTE, 0U, kPORT_MuxAlt3); - - SIM->SOPT5 = ((SIM->SOPT5 & - /* Mask bits to zero which are setting */ - (~(SIM_SOPT5_LPUART1TXSRC_MASK | SIM_SOPT5_LPUART1RXSRC_MASK))) - /* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */ - | SIM_SOPT5_LPUART1TXSRC(SOPT5_LPUART1TXSRC_LPUART_TX) - /* LPUART0 Receive Data Source Select: LPUART_RX pin. */ - | SIM_SOPT5_LPUART1RXSRC(SOPT5_LPUART1RXSRC_LPUART_RX)); - - BOARD_BootClockRUN(); - SystemCoreClockUpdate(); - CLOCK_SetLpuart1Clock(1); - -#if CFG_TUSB_OS == OPT_OS_NONE - // 1ms tick timer - SysTick_Config(SystemCoreClock / 1000); -#elif CFG_TUSB_OS == OPT_OS_FREERTOS - // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); -#endif - - lpuart_config_t uart_config; - LPUART_GetDefaultConfig(&uart_config); - uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; - uart_config.enableTx = true; - uart_config.enableRx = true; - LPUART_Init(UART_PORT, &uart_config, CLOCK_GetFreq(kCLOCK_McgIrc48MClk)); - - // USB - CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U); -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) -{ - if (state) { - LED_GPIO->PDDR |= GPIO_FIT_REG((1UL << LED_PIN)); - } else { - LED_GPIO->PDDR &= GPIO_FIT_REG(~(1UL << LED_PIN)); - } -// GPIO_PinWrite(GPIOA, 1, state ? LED_STATE_ON : (1-LED_STATE_ON) ); -// GPIO_PinWrite(GPIOA, 2, state ? (1-LED_STATE_ON) : LED_STATE_ON ); -} - -uint32_t board_button_read(void) -{ -#ifdef BUTTON_PIN - return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); -#else - return 0; -#endif -} - -int board_uart_read(uint8_t* buf, int len) -{ - LPUART_ReadBlocking(UART_PORT, buf, len); - return len; -} - -int board_uart_write(void const * buf, int len) -{ - LPUART_WriteBlocking(UART_PORT, (uint8_t const*) buf, len); - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; -void SysTick_Handler(void) -{ - system_ticks++; -} - -uint32_t board_millis(void) -{ - return system_ticks; -} -#endif diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld b/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld new file mode 100644 index 000000000..f478a99c7 --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld @@ -0,0 +1,216 @@ +/* +** ################################################################### +** Processors: K32L2B31VFM0A +** K32L2B31VFT0A +** K32L2B31VLH0A +** K32L2B31VMP0A +** +** Compiler: GNU C Compiler +** Reference manual: K32L2B3xRM, Rev.0, July 2019 +** Version: rev. 1.0, 2019-07-30 +** Build: b190930 +** +** Abstract: +** Linker file for the GNU C Compiler +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2019 NXP +** All rights reserved. +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** ################################################################### +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; + +/* Specify the memory areas */ +MEMORY +{ + m_interrupts (RX) : ORIGIN = 0x00008000, LENGTH = 0x00000200 + m_flash_config (RX) : ORIGIN = 0x00008400, LENGTH = 0x00000010 + m_text (RX) : ORIGIN = 0x00008410, LENGTH = 0x00037BF0 + m_data (RW) : ORIGIN = 0x1FFFE000, LENGTH = 0x00008000 +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into internal flash */ + .interrupts : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } > m_interrupts + + .flash_config : + { + . = ALIGN(4); + KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */ + . = ALIGN(4); + } > m_flash_config + + /* The program code and other data goes into internal flash */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN(4); + } > m_text + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > m_text + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } > m_text + + .ctors : + { + __CTOR_LIST__ = .; + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __CTOR_END__ = .; + } > m_text + + .dtors : + { + __DTOR_LIST__ = .; + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __DTOR_END__ = .; + } > m_text + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } > m_text + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } > m_text + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } > m_text + + __etext = .; /* define a global symbol at end of code */ + __DATA_ROM = .; /* Symbol is used by startup for data initialization */ + + /* reserve MTB memory at the beginning of m_data */ + .mtb : /* MTB buffer address as defined by the hardware */ + { + . = ALIGN(8); + _mtb_start = .; + KEEP(*(.mtb_buf)) /* need to KEEP Micro Trace Buffer as not referenced by application */ + . = ALIGN(8); + _mtb_end = .; + } > m_data + + .data : AT(__DATA_ROM) + { + . = ALIGN(4); + __DATA_RAM = .; + __data_start__ = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + KEEP(*(.jcr*)) + . = ALIGN(4); + __data_end__ = .; /* define a global symbol at data end */ + } > m_data + + __DATA_END = __DATA_ROM + (__data_end__ - __data_start__); + text_end = ORIGIN(m_text) + LENGTH(m_text); + ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") + + /* Uninitialized data section */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + . = ALIGN(4); + __START_BSS = .; + __bss_start__ = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + __END_BSS = .; + } > m_data + + .heap : + { + . = ALIGN(8); + __end__ = .; + PROVIDE(end = .); + __HeapBase = .; + . += HEAP_SIZE; + __HeapLimit = .; + __heap_limit = .; /* Add for _sbrk */ + } > m_data + + .stack : + { + . = ALIGN(8); + . += STACK_SIZE; + } > m_data + + /* Initializes stack on the end of block */ + __StackTop = ORIGIN(m_data) + LENGTH(m_data); + __StackLimit = __StackTop - STACK_SIZE; + PROVIDE(__stack = __StackTop); + + .ARM.attributes 0 : { *(.ARM.attributes) } + + ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap") +} diff --git a/hw/bsp/kinetis_k32l2/family.c b/hw/bsp/kinetis_k32l2/family.c new file mode 100644 index 000000000..92f5ba6d3 --- /dev/null +++ b/hw/bsp/kinetis_k32l2/family.c @@ -0,0 +1,170 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (tinyusb.org) + * Copyright (c) 2020, Koji Kitayama + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "fsl_gpio.h" +#include "fsl_port.h" +#include "fsl_clock.h" +#include "fsl_lpuart.h" + +#include "clock_config.h" +#include "bsp/board_api.h" +#include "board.h" + + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB0_IRQHandler(void) { + tud_int_handler(0); +} + +void board_init(void) { + /* Enable port clocks for GPIO pins */ + CLOCK_EnableClock(kCLOCK_PortA); + CLOCK_EnableClock(kCLOCK_PortB); + CLOCK_EnableClock(kCLOCK_PortC); + CLOCK_EnableClock(kCLOCK_PortD); + CLOCK_EnableClock(kCLOCK_PortE); + + BOARD_InitBootPins(); + BOARD_BootClockRUN(); + SystemCoreClockUpdate(); + + gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0}; + GPIO_PinInit(LED_GPIO, LED_PIN, &led_config); + PORT_SetPinMux(LED_PORT, LED_PIN, kPORT_MuxAsGpio); + +#ifdef BUTTON_PIN + gpio_pin_config_t button_config = {kGPIO_DigitalInput, 0}; + GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); + const port_pin_config_t BUTTON_CFG = { + kPORT_PullUp, + kPORT_FastSlewRate, + kPORT_PassiveFilterDisable, +#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN + kPORT_OpenDrainDisable, +#endif + kPORT_LowDriveStrength, + kPORT_MuxAsGpio, +#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK + kPORT_UnlockRegister +#endif + }; + PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG); +#endif + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + lpuart_config_t uart_config; + LPUART_GetDefaultConfig(&uart_config); + uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; + uart_config.enableTx = true; + uart_config.enableRx = true; + LPUART_Init(UART_PORT, &uart_config, UART_CLOCK_SOURCE_HZ); + + // USB + CLOCK_EnableUsbfs0Clock(USB_CLOCK_SOURCE, 48000000U); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { + GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); +} + +uint32_t board_button_read(void) { +#ifdef BUTTON_PIN + return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); +#else + return 0; +#endif +} + +int board_uart_read(uint8_t* buf, int len) { +#if 0 /* + Use this version if want the LED to blink during BOARD=board_test, + without having to hit a key. + */ + if( 0U != (kLPUART_RxDataRegFullFlag & LPUART_GetStatusFlags( UART_PORT )) ) + { + LPUART_ReadBlocking(UART_PORT, buf, len); + return len; + } + + return( 0 ); +#else /* Wait for 'len' characters to come in */ + + LPUART_ReadBlocking(UART_PORT, buf, len); + return len; + +#endif +} + +int board_uart_write(void const* buf, int len) { + LPUART_WriteBlocking(UART_PORT, (uint8_t const*) buf, len); + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; +} + +uint32_t board_millis(void) { + return system_ticks; +} + +#endif + +#ifndef __ICCARM__ +// Implement _start() since we use linker flag '-nostartfiles'. +// Requires defined __STARTUP_CLEAR_BSS, +extern int main(void); + +TU_ATTR_UNUSED void _start(void) { + // called by startup code + main(); + while (1) {} +} + +#ifdef __clang__ +void _exit (int __status) { + while (1) {} +} +#endif + +#endif diff --git a/hw/bsp/kinetis_k32l2/family.cmake b/hw/bsp/kinetis_k32l2/family.cmake new file mode 100644 index 000000000..406ae99d3 --- /dev/null +++ b/hw/bsp/kinetis_k32l2/family.cmake @@ -0,0 +1,112 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk) +set(CMSIS_DIR ${TOP}/lib/CMSIS_5) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS KINETIS_K32L CACHE INTERNAL "") + + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + # LD_FILE and STARTUP_FILE can be defined in board.cmake + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ${SDK_DIR}/drivers/gpio/fsl_gpio.c + ${SDK_DIR}/drivers/lpuart/fsl_lpuart.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c + ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + __STARTUP_CLEAR_BSS + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMSIS_DIR}/CMSIS/Core/Include + ${SDK_DIR}/devices/${MCU_VARIANT} + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + ${SDK_DIR}/drivers/common + ${SDK_DIR}/drivers/gpio + ${SDK_DIR}/drivers/lpuart + ${SDK_DIR}/drivers/port + ${SDK_DIR}/drivers/smc + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + --specs=nosys.specs --specs=nano.specs + -nostartfiles + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_KINETIS_K32L ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/nxp/khci/dcd_khci.c + ${TOP}/src/portable/nxp/khci/hcd_khci.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) + + if (DEFINED TEENSY_MCU) + family_add_bin_hex(${TARGET}) + family_flash_teensy(${TARGET}) + endif () +endfunction() diff --git a/hw/bsp/kinetis_k32l2/family.mk b/hw/bsp/kinetis_k32l2/family.mk index 0bfd57d29..e18348d4d 100644 --- a/hw/bsp/kinetis_k32l2/family.mk +++ b/hw/bsp/kinetis_k32l2/family.mk @@ -1,6 +1,5 @@ UF2_FAMILY_ID = 0x7f83e793 SDK_DIR = hw/mcu/nxp/mcux-sdk -DEPS_SUBMODULES += $(SDK_DIR) lib/CMSIS_5 MCU_DIR = $(SDK_DIR)/devices/$(MCU) include $(TOP)/$(BOARD_PATH)/board.mk @@ -9,7 +8,9 @@ CPU_CORE ?= cortex-m0plus CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_KINETIS_K32L -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostartfiles \ + -specs=nosys.specs -specs=nano.specs SRC_C += \ src/portable/nxp/khci/dcd_khci.c \ @@ -25,10 +26,10 @@ INC += \ $(TOP)/$(MCU_DIR) \ $(TOP)/$(MCU_DIR)/project_template \ $(TOP)/$(MCU_DIR)/drivers \ - $(TOP)/$(SDK_DIR)/drivers/smc \ $(TOP)/$(SDK_DIR)/drivers/common \ $(TOP)/$(SDK_DIR)/drivers/gpio \ - $(TOP)/$(SDK_DIR)/drivers/port \ $(TOP)/$(SDK_DIR)/drivers/lpuart \ + $(TOP)/$(SDK_DIR)/drivers/port \ + $(TOP)/$(SDK_DIR)/drivers/smc \ SRC_S += $(MCU_DIR)/gcc/startup_$(MCU).S -- cgit v1.3.1 From c717e52ab2453f7672b16f2d63cd70558950ef33 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 May 2024 17:54:44 +0700 Subject: add cmake for lpc11 --- .../device/audio_4_channel_mic_freertos/skip.txt | 1 + .../kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h | 2 +- hw/bsp/lpc11/FreeRTOSConfig/FreeRTOSConfig.h | 178 ++++++++++++++++++ hw/bsp/lpc11/boards/lpcxpresso11u37/board.cmake | 19 ++ hw/bsp/lpc11/boards/lpcxpresso11u37/board.h | 98 ++++++++++ .../lpc11/boards/lpcxpresso11u37/lpcxpresso11u37.c | 208 --------------------- hw/bsp/lpc11/boards/lpcxpresso11u68/board.cmake | 12 ++ hw/bsp/lpc11/boards/lpcxpresso11u68/board.h | 27 +++ hw/bsp/lpc11/boards/lpcxpresso11u68/board.mk | 1 - .../lpc11/boards/lpcxpresso11u68/lpcxpresso11u68.c | 135 ------------- hw/bsp/lpc11/family.c | 120 ++++++++++++ hw/bsp/lpc11/family.cmake | 104 +++++++++++ hw/bsp/lpc11/family.mk | 5 +- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 10 + 14 files changed, 572 insertions(+), 348 deletions(-) create mode 100644 hw/bsp/lpc11/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/lpc11/boards/lpcxpresso11u37/board.cmake create mode 100644 hw/bsp/lpc11/boards/lpcxpresso11u37/board.h delete mode 100644 hw/bsp/lpc11/boards/lpcxpresso11u37/lpcxpresso11u37.c create mode 100644 hw/bsp/lpc11/boards/lpcxpresso11u68/board.cmake create mode 100644 hw/bsp/lpc11/boards/lpcxpresso11u68/board.h delete mode 100644 hw/bsp/lpc11/boards/lpcxpresso11u68/lpcxpresso11u68.c create mode 100644 hw/bsp/lpc11/family.c create mode 100644 hw/bsp/lpc11/family.cmake diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt index eb434c23b..21683518c 100644 --- a/examples/device/audio_4_channel_mic_freertos/skip.txt +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -10,5 +10,6 @@ mcu:SAMX7X mcu:VALENTYUSB_EPTRI mcu:RAXXX mcu:STM32L0 +board:lpcxpresso11u37 family:broadcom_32bit family:broadcom_64bit diff --git a/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h index 133728596..e6604d360 100644 --- a/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h @@ -147,7 +147,7 @@ //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header -#define configPRIO_BITS 4 +#define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 2 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* Define to trap errors during development. */ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) + #define configASSERT(_exp) \ + do {\ + if ( !(_exp) ) { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ + taskDISABLE_INTERRUPTS(); \ + __asm("BKPT #0\n"); \ + }\ + }\ + } while(0) +#else + #define configASSERT( x ) +#endif + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 2 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< Date: Thu, 2 May 2024 17:56:36 +0700 Subject: update clang format --- .clang-format | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..0fd168e5a --- /dev/null +++ b/.clang-format @@ -0,0 +1,66 @@ +# Generated from CLion C/C++ Code Style settings +BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: None +AlignOperands: Align +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: Always +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Always +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterReturnType: None +AlwaysBreakTemplateDeclarations: Yes +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: true +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +ColumnLimit: 0 +CompactNamespaces: false +ContinuationIndentWidth: 4 +IndentCaseLabels: true +IndentPPDirectives: BeforeHash +IndentWidth: 2 +KeepEmptyLinesAtTheStartOfBlocks: true +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: All +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PointerAlignment: Right +ReflowComments: false +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 0 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: true +SpacesInParentheses: false +SpacesInSquareBrackets: false +TabWidth: 2 +UseTab: Never -- cgit v1.3.1 From 19cb2f1a3cb7b281101b0465128d4bda23e89d34 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 May 2024 18:13:53 +0700 Subject: add cmake to lpc1347 --- .../device/audio_4_channel_mic_freertos/skip.txt | 1 + hw/bsp/lpc13/FreeRTOSConfig/FreeRTOSConfig.h | 178 +++++++++++++++++++++ hw/bsp/lpc13/boards/lpcxpresso1347/board.cmake | 11 ++ hw/bsp/lpc13/boards/lpcxpresso1347/board.h | 46 ++++++ .../lpc13/boards/lpcxpresso1347/lpcxpresso1347.c | 152 ------------------ hw/bsp/lpc13/family.c | 105 ++++++++++++ hw/bsp/lpc13/family.cmake | 102 ++++++++++++ hw/bsp/lpc13/family.mk | 3 +- 8 files changed, 445 insertions(+), 153 deletions(-) create mode 100644 hw/bsp/lpc13/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/lpc13/boards/lpcxpresso1347/board.cmake create mode 100644 hw/bsp/lpc13/boards/lpcxpresso1347/board.h delete mode 100644 hw/bsp/lpc13/boards/lpcxpresso1347/lpcxpresso1347.c create mode 100644 hw/bsp/lpc13/family.c create mode 100644 hw/bsp/lpc13/family.cmake diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt index 21683518c..0b689192d 100644 --- a/examples/device/audio_4_channel_mic_freertos/skip.txt +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -11,5 +11,6 @@ mcu:VALENTYUSB_EPTRI mcu:RAXXX mcu:STM32L0 board:lpcxpresso11u37 +board:lpcxpresso1347 family:broadcom_32bit family:broadcom_64bit diff --git a/hw/bsp/lpc13/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/lpc13/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..a56028d5d --- /dev/null +++ b/hw/bsp/lpc13/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,178 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-parameter" + #endif + + #include "chip.h" + + #ifdef __GNUC__ + #pragma GCC diagnostic pop + #endif +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 2 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* Define to trap errors during development. */ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) + #define configASSERT(_exp) \ + do {\ + if ( !(_exp) ) { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ + taskDISABLE_INTERRUPTS(); \ + __asm("BKPT #0\n"); \ + }\ + }\ + } while(0) +#else + #define configASSERT( x ) +#endif + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 3 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< Date: Thu, 2 May 2024 18:24:47 +0700 Subject: add cmake for lpc15 --- hw/bsp/lpc15/FreeRTOSConfig/FreeRTOSConfig.h | 179 +++++++++++++++++++++++++ hw/bsp/lpc15/boards/lpcxpresso1549/board.cmake | 11 ++ hw/bsp/lpc15/family.c | 11 ++ hw/bsp/lpc15/family.cmake | 104 ++++++++++++++ hw/bsp/lpc15/family.mk | 2 +- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 1 + 6 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 hw/bsp/lpc15/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/lpc15/boards/lpcxpresso1549/board.cmake create mode 100644 hw/bsp/lpc15/family.cmake diff --git a/hw/bsp/lpc15/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/lpc15/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..33bc22b37 --- /dev/null +++ b/hw/bsp/lpc15/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,179 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-parameter" + #pragma GCC diagnostic ignored "-Wstrict-prototypes" + #endif + + #include "chip.h" + + #ifdef __GNUC__ + #pragma GCC diagnostic pop + #endif +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 2 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* Define to trap errors during development. */ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) + #define configASSERT(_exp) \ + do {\ + if ( !(_exp) ) { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ + taskDISABLE_INTERRUPTS(); \ + __asm("BKPT #0\n"); \ + }\ + }\ + } while(0) +#else + #define configASSERT( x ) +#endif + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 3 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< Date: Thu, 2 May 2024 18:26:01 +0700 Subject: update cmake ci --- .github/workflows/build_cmake.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 65de47e8d..0aed5f992 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -37,8 +37,10 @@ jobs: matrix: family: # Alphabetical order + - 'broadcom_32bit' - 'imxrt' - - 'kinetis_k kinetis_kl' + - 'kinetis_k kinetis_kl kinetis_k32l2' + - 'lpc11 lpc13 lpc15' - 'lpc17 lpc18 lpc40 lpc43' - 'lpc54 lpc55' - 'mcx' -- cgit v1.3.1 From 68a4d0c8db0beec4fee22dab003f1e5ec39da310 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 May 2024 20:43:27 +0700 Subject: add cmake to lpc51 --- hw/bsp/lpc51/FreeRTOSConfig/FreeRTOSConfig.h | 169 +++++++++++++++++++ hw/bsp/lpc51/boards/lpcxpresso51u68/board.cmake | 13 ++ hw/bsp/lpc51/boards/lpcxpresso51u68/board.h | 57 +++++++ .../lpc51/boards/lpcxpresso51u68/lpcxpresso51u68.c | 179 --------------------- hw/bsp/lpc51/family.c | 141 ++++++++++++++++ hw/bsp/lpc51/family.cmake | 123 ++++++++++++++ hw/bsp/lpc51/family.mk | 11 +- src/tusb_option.h | 3 +- 8 files changed, 512 insertions(+), 184 deletions(-) create mode 100644 hw/bsp/lpc51/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/lpc51/boards/lpcxpresso51u68/board.cmake create mode 100644 hw/bsp/lpc51/boards/lpcxpresso51u68/board.h delete mode 100644 hw/bsp/lpc51/boards/lpcxpresso51u68/lpcxpresso51u68.c create mode 100644 hw/bsp/lpc51/family.c create mode 100644 hw/bsp/lpc51/family.cmake diff --git a/hw/bsp/lpc51/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/lpc51/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..e6604d360 --- /dev/null +++ b/hw/bsp/lpc51/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,169 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "fsl_device_registers.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 2 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* Define to trap errors during development. */ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) + #define configASSERT(_exp) \ + do {\ + if ( !(_exp) ) { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ + taskDISABLE_INTERRUPTS(); \ + __asm("BKPT #0\n"); \ + }\ + }\ + } while(0) +#else + #define configASSERT( x ) +#endif + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 2 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< Date: Thu, 2 May 2024 21:28:43 +0700 Subject: add cmake to msp432e4 --- .github/workflows/build_cmake.yml | 3 +- hw/bsp/msp430/FreeRTOSConfig/FreeRTOSConfig.h | 80 +++++++++++ hw/bsp/msp432e4/FreeRTOSConfig/FreeRTOSConfig.h | 149 +++++++++++++++++++++ hw/bsp/msp432e4/boards/msp_exp432e401y/board.cmake | 8 ++ hw/bsp/msp432e4/boards/msp_exp432e401y/board.mk | 3 + hw/bsp/msp432e4/family.cmake | 101 ++++++++++++++ hw/bsp/msp432e4/family.mk | 23 ++-- 7 files changed, 351 insertions(+), 16 deletions(-) create mode 100644 hw/bsp/msp430/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/msp432e4/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/msp432e4/boards/msp_exp432e401y/board.cmake create mode 100644 hw/bsp/msp432e4/boards/msp_exp432e401y/board.mk create mode 100644 hw/bsp/msp432e4/family.cmake diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 0aed5f992..cbe36ae79 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -42,8 +42,9 @@ jobs: - 'kinetis_k kinetis_kl kinetis_k32l2' - 'lpc11 lpc13 lpc15' - 'lpc17 lpc18 lpc40 lpc43' - - 'lpc54 lpc55' + - 'lpc51 lpc54 lpc55' - 'mcx' + - 'msp432e4' - 'nrf' - 'ra' - 'rp2040' diff --git a/hw/bsp/msp430/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/msp430/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..4049fba65 --- /dev/null +++ b/hw/bsp/msp430/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,80 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "msp430.h" +#endif + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned long ) 7995392 ) /* Clock setup from main.c in the demo application. */ +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMAX_PRIORITIES ( 4 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 50 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 1700 ) ) +#define configMAX_TASK_NAME_LEN ( 8 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 1 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/hw/bsp/msp432e4/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/msp432e4/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..3dd5a1ee1 --- /dev/null +++ b/hw/bsp/msp432e4/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "msp.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 3 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< Date: Fri, 3 May 2024 10:59:29 +0700 Subject: add cmake for saml2x --- hw/bsp/samd21/family.cmake | 8 +- hw/bsp/samd21/family.mk | 6 +- hw/bsp/saml2x/boards/atsaml21_xpro/board.cmake | 9 ++ hw/bsp/saml2x/boards/atsaml21_xpro/board.mk | 4 +- .../boards/atsaml21_xpro/saml21j18b_flash.ld | 2 + hw/bsp/saml2x/boards/saml22_feather/board.cmake | 9 ++ hw/bsp/saml2x/boards/saml22_feather/board.mk | 4 +- .../saml2x/boards/saml22_feather/saml22_feather.ld | 4 +- hw/bsp/saml2x/boards/sensorwatch_m0/board.cmake | 9 ++ hw/bsp/saml2x/boards/sensorwatch_m0/board.mk | 4 +- .../saml2x/boards/sensorwatch_m0/sensorwatch_m0.ld | 4 +- hw/bsp/saml2x/family.c | 55 +++++----- hw/bsp/saml2x/family.cmake | 116 +++++++++++++++++++++ hw/bsp/saml2x/family.mk | 45 ++++---- 14 files changed, 216 insertions(+), 63 deletions(-) create mode 100644 hw/bsp/saml2x/boards/atsaml21_xpro/board.cmake create mode 100644 hw/bsp/saml2x/boards/saml22_feather/board.cmake create mode 100644 hw/bsp/saml2x/boards/sensorwatch_m0/board.cmake create mode 100644 hw/bsp/saml2x/family.cmake diff --git a/hw/bsp/samd21/family.cmake b/hw/bsp/samd21/family.cmake index 540a0ee33..e081aedaf 100644 --- a/hw/bsp/samd21/family.cmake +++ b/hw/bsp/samd21/family.cmake @@ -26,9 +26,7 @@ function(add_board_target BOARD_TARGET) message(FATAL_ERROR "LD_FILE_${CMAKE_C_COMPILER_ID} not defined") endif () - if (NOT DEFINED STARTUP_FILE_GNU) - set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_samd21.c) - endif () + set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_samd21.c) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) add_library(${BOARD_TARGET} STATIC @@ -50,7 +48,9 @@ function(add_board_target BOARD_TARGET) ${SDK_DIR}/hri ${SDK_DIR}/CMSIS/Include ) - target_compile_definitions(${BOARD_TARGET} PUBLIC CONF_DFLL_OVERWRITE_CALIBRATION=0) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CONF_DFLL_OVERWRITE_CALIBRATION=0 + ) update_board(${BOARD_TARGET}) diff --git a/hw/bsp/samd21/family.mk b/hw/bsp/samd21/family.mk index aabcff4a2..08c5c5b0e 100644 --- a/hw/bsp/samd21/family.mk +++ b/hw/bsp/samd21/family.mk @@ -25,14 +25,14 @@ SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ ${SDK_DIR}/gcc/gcc/startup_samd21.c \ ${SDK_DIR}/gcc/system_samd21.c \ + ${SDK_DIR}/hal/src/hal_atomic.c \ ${SDK_DIR}/hpl/gclk/hpl_gclk.c \ ${SDK_DIR}/hpl/pm/hpl_pm.c \ ${SDK_DIR}/hpl/sysctrl/hpl_sysctrl.c \ - ${SDK_DIR}/hal/src/hal_atomic.c INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/${SDK_DIR}/ \ + $(TOP)/${SDK_DIR} \ $(TOP)/${SDK_DIR}/config \ $(TOP)/${SDK_DIR}/include \ $(TOP)/${SDK_DIR}/hal/include \ @@ -40,7 +40,7 @@ INC += \ $(TOP)/${SDK_DIR}/hpl/pm/ \ $(TOP)/${SDK_DIR}/hpl/port \ $(TOP)/${SDK_DIR}/hri \ - $(TOP)/${SDK_DIR}/CMSIS/Include + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ # flash using bossac at least version 1.8 # can be found in arduino15/packages/arduino/tools/bossac/ diff --git a/hw/bsp/saml2x/boards/atsaml21_xpro/board.cmake b/hw/bsp/saml2x/boards/atsaml21_xpro/board.cmake new file mode 100644 index 000000000..6312ff89d --- /dev/null +++ b/hw/bsp/saml2x/boards/atsaml21_xpro/board.cmake @@ -0,0 +1,9 @@ +set(MCU_VARIANT saml21) +set(JLINK_DEVICE ATSAML21J18) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/saml21j18b_flash.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAML21J18B__ + ) +endfunction() diff --git a/hw/bsp/saml2x/boards/atsaml21_xpro/board.mk b/hw/bsp/saml2x/boards/atsaml21_xpro/board.mk index 5b9acb90b..75179fc58 100644 --- a/hw/bsp/saml2x/boards/atsaml21_xpro/board.mk +++ b/hw/bsp/saml2x/boards/atsaml21_xpro/board.mk @@ -1,6 +1,6 @@ -CFLAGS += -D__SAML21J18B__ -DCFG_EXAMPLE_VIDEO_READONLY +MCU_VARIANT = saml21 -SAML_VARIANT = saml21 +CFLAGS += -D__SAML21J18B__ # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/saml21j18b_flash.ld diff --git a/hw/bsp/saml2x/boards/atsaml21_xpro/saml21j18b_flash.ld b/hw/bsp/saml2x/boards/atsaml21_xpro/saml21j18b_flash.ld index 48cacd526..f9523451b 100644 --- a/hw/bsp/saml2x/boards/atsaml21_xpro/saml21j18b_flash.ld +++ b/hw/bsp/saml2x/boards/atsaml21_xpro/saml21j18b_flash.ld @@ -31,6 +31,8 @@ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) +ENTRY(Reset_Handler) + /* Memory Spaces Definitions */ MEMORY { diff --git a/hw/bsp/saml2x/boards/saml22_feather/board.cmake b/hw/bsp/saml2x/boards/saml22_feather/board.cmake new file mode 100644 index 000000000..7db751e45 --- /dev/null +++ b/hw/bsp/saml2x/boards/saml22_feather/board.cmake @@ -0,0 +1,9 @@ +set(MCU_VARIANT saml22) +set(JLINK_DEVICE ATSAML22J18) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAML22J18A__ + ) +endfunction() diff --git a/hw/bsp/saml2x/boards/saml22_feather/board.mk b/hw/bsp/saml2x/boards/saml22_feather/board.mk index 0adfdd62c..76d86de25 100644 --- a/hw/bsp/saml2x/boards/saml22_feather/board.mk +++ b/hw/bsp/saml2x/boards/saml22_feather/board.mk @@ -1,6 +1,6 @@ -CFLAGS += -D__SAML22J18A__ -DCFG_EXAMPLE_VIDEO_READONLY +MCU_VARIANT = saml22 -SAML_VARIANT = saml22 +CFLAGS += -D__SAML22J18A__ # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/$(BOARD).ld diff --git a/hw/bsp/saml2x/boards/saml22_feather/saml22_feather.ld b/hw/bsp/saml2x/boards/saml22_feather/saml22_feather.ld index 372107ff8..a04305be7 100644 --- a/hw/bsp/saml2x/boards/saml22_feather/saml22_feather.ld +++ b/hw/bsp/saml2x/boards/saml22_feather/saml22_feather.ld @@ -32,6 +32,8 @@ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) +ENTRY(Reset_Handler) + /* Memory Spaces Definitions */ MEMORY { @@ -42,8 +44,6 @@ MEMORY /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; -ENTRY(Reset_Handler) - /* Section Definitions */ SECTIONS { diff --git a/hw/bsp/saml2x/boards/sensorwatch_m0/board.cmake b/hw/bsp/saml2x/boards/sensorwatch_m0/board.cmake new file mode 100644 index 000000000..162ef127b --- /dev/null +++ b/hw/bsp/saml2x/boards/sensorwatch_m0/board.cmake @@ -0,0 +1,9 @@ +set(MCU_VARIANT saml22) +set(JLINK_DEVICE ATSAML21J18) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAML22J18A__ + ) +endfunction() diff --git a/hw/bsp/saml2x/boards/sensorwatch_m0/board.mk b/hw/bsp/saml2x/boards/sensorwatch_m0/board.mk index 0adfdd62c..76d86de25 100644 --- a/hw/bsp/saml2x/boards/sensorwatch_m0/board.mk +++ b/hw/bsp/saml2x/boards/sensorwatch_m0/board.mk @@ -1,6 +1,6 @@ -CFLAGS += -D__SAML22J18A__ -DCFG_EXAMPLE_VIDEO_READONLY +MCU_VARIANT = saml22 -SAML_VARIANT = saml22 +CFLAGS += -D__SAML22J18A__ # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/$(BOARD).ld diff --git a/hw/bsp/saml2x/boards/sensorwatch_m0/sensorwatch_m0.ld b/hw/bsp/saml2x/boards/sensorwatch_m0/sensorwatch_m0.ld index 372107ff8..a04305be7 100644 --- a/hw/bsp/saml2x/boards/sensorwatch_m0/sensorwatch_m0.ld +++ b/hw/bsp/saml2x/boards/sensorwatch_m0/sensorwatch_m0.ld @@ -32,6 +32,8 @@ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) +ENTRY(Reset_Handler) + /* Memory Spaces Definitions */ MEMORY { @@ -42,8 +44,6 @@ MEMORY /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; -ENTRY(Reset_Handler) - /* Section Definitions */ SECTIONS { diff --git a/hw/bsp/saml2x/family.c b/hw/bsp/saml2x/family.c index 438fe8bfa..11977b036 100644 --- a/hw/bsp/saml2x/family.c +++ b/hw/bsp/saml2x/family.c @@ -25,19 +25,29 @@ */ #include "sam.h" -#include "bsp/board_api.h" -#include "board.h" + +// Suppress warning caused by mcu driver +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif #include "hal/include/hal_gpio.h" #include "hal/include/hal_init.h" #include "hpl/gclk/hpl_gclk_base.h" #include "hpl_mclk_config.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#include "bsp/board_api.h" +#include "board.h" + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB_Handler(void) -{ +void USB_Handler(void) { tud_int_handler(0); } @@ -50,8 +60,7 @@ void USB_Handler(void) /* Not referenced GCLKs, initialized last */ #define _GCLK_INIT_LAST 0x0000001F -void board_init(void) -{ +void board_init(void) { // Clock init ( follow hpl_init.c ) hri_nvmctrl_set_CTRLB_RWS_bf(NVMCTRL, CONF_NVM_WAIT_STATE); @@ -84,7 +93,7 @@ void board_init(void) gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); gpio_set_pin_pull_mode(BUTTON_PIN, BUTTON_STATE_ACTIVE ? GPIO_PULL_DOWN : GPIO_PULL_UP); -#if CFG_TUSB_OS == OPT_OS_FREERTOS +#if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif @@ -121,43 +130,39 @@ void board_init(void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ +void board_led_write(bool state) { gpio_set_pin_level(LED_PIN, state); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { // button is active low return gpio_get_pin_level(BUTTON_PIN) ? 0 : 1; } -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; return 0; } -int board_uart_write(void const * buf, int len) -{ - (void) buf; (void) len; +int board_uart_write(void const* buf, int len) { + (void) buf; + (void) len; return 0; } -#if CFG_TUSB_OS == OPT_OS_NONE +#if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; - -void SysTick_Handler (void) -{ +void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } + #endif -void _init(void) -{ + +void _init(void) { } diff --git a/hw/bsp/saml2x/family.cmake b/hw/bsp/saml2x/family.cmake new file mode 100644 index 000000000..d8a62aef3 --- /dev/null +++ b/hw/bsp/saml2x/family.cmake @@ -0,0 +1,116 @@ +include_guard() + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +set(SDK_DIR ${TOP}/hw/mcu/microchip/${MCU_VARIANT}) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS SAML21 SAML22 CACHE INTERNAL "") +set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -f target/at91samdXX.cfg") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + set(LD_FILE_Clang ${LD_FILE_GNU}) + if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) + message(FATAL_ERROR "LD_FILE_${CMAKE_C_COMPILER_ID} not defined") + endif () + + set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_${MCU_VARIANT}.c) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/gcc/system_${MCU_VARIANT}.c + ${SDK_DIR}/hal/src/hal_atomic.c + ${SDK_DIR}/hpl/gclk/hpl_gclk.c + ${SDK_DIR}/hpl/mclk/hpl_mclk.c + ${SDK_DIR}/hpl/osc32kctrl/hpl_osc32kctrl.c + ${SDK_DIR}/hpl/oscctrl/hpl_oscctrl.c + ${SDK_DIR}/hpl/pm/hpl_pm.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR} + ${SDK_DIR}/config + ${SDK_DIR}/include + ${SDK_DIR}/hal/include + ${SDK_DIR}/hal/utils/include + ${SDK_DIR}/hpl/pm + ${SDK_DIR}/hpl/port + ${SDK_DIR}/hri + ${CMSIS_5}/CMSIS/Core/Include + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CONF_OSC32K_CALIB_ENABLE=0 + CFG_EXAMPLE_VIDEO_READONLY + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_SAML22 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/microchip/samd/dcd_samd.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_jlink(${TARGET}) + #family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) +endfunction() diff --git a/hw/bsp/saml2x/family.mk b/hw/bsp/saml2x/family.mk index 59dbc9a25..e01d7522e 100644 --- a/hw/bsp/saml2x/family.mk +++ b/hw/bsp/saml2x/family.mk @@ -1,14 +1,14 @@ UF2_FAMILY_ID = 0x68ed2b88 -DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/microchip -MCU_DIR = hw/mcu/microchip/$(SAML_VARIANT) +SDK_DIR = hw/mcu/microchip/$(MCU_VARIANT) include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus CFLAGS += \ - -nostdlib -nostartfiles \ + -flto \ -DCONF_OSC32K_CALIB_ENABLE=0 \ - -DCFG_TUSB_MCU=OPT_MCU_SAML22 + -DCFG_TUSB_MCU=OPT_MCU_SAML22 \ + -DCFG_EXAMPLE_VIDEO_READONLY \ # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=redundant-decls @@ -16,29 +16,32 @@ CFLAGS += -Wno-error=redundant-decls # SAM driver is flooded with -Wcast-qual which slow down complication significantly CFLAGS_SKIP += -Wcast-qual -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ - $(MCU_DIR)/gcc/gcc/startup_$(SAML_VARIANT).c \ - $(MCU_DIR)/gcc/system_$(SAML_VARIANT).c \ - $(MCU_DIR)/hpl/gclk/hpl_gclk.c \ - $(MCU_DIR)/hpl/mclk/hpl_mclk.c \ - $(MCU_DIR)/hpl/pm/hpl_pm.c \ - $(MCU_DIR)/hpl/osc32kctrl/hpl_osc32kctrl.c \ - $(MCU_DIR)/hpl/oscctrl/hpl_oscctrl.c \ - $(MCU_DIR)/hal/src/hal_atomic.c + $(SDK_DIR)/gcc/gcc/startup_$(MCU_VARIANT).c \ + $(SDK_DIR)/gcc/system_$(MCU_VARIANT).c \ + $(SDK_DIR)/hal/src/hal_atomic.c \ + $(SDK_DIR)/hpl/gclk/hpl_gclk.c \ + $(SDK_DIR)/hpl/mclk/hpl_mclk.c \ + $(SDK_DIR)/hpl/osc32kctrl/hpl_osc32kctrl.c \ + $(SDK_DIR)/hpl/oscctrl/hpl_oscctrl.c \ + $(SDK_DIR)/hpl/pm/hpl_pm.c \ INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/$(MCU_DIR) \ - $(TOP)/$(MCU_DIR)/config \ - $(TOP)/$(MCU_DIR)/include \ - $(TOP)/$(MCU_DIR)/hal/include \ - $(TOP)/$(MCU_DIR)/hal/utils/include \ - $(TOP)/$(MCU_DIR)/hpl/port \ - $(TOP)/$(MCU_DIR)/hri \ - $(TOP)/lib/CMSIS_5/CMSIS/Core/Include + $(TOP)/${SDK_DIR} \ + $(TOP)/${SDK_DIR}/config \ + $(TOP)/${SDK_DIR}/include \ + $(TOP)/${SDK_DIR}/hal/include \ + $(TOP)/${SDK_DIR}/hal/utils/include \ + $(TOP)/${SDK_DIR}/hpl/pm/ \ + $(TOP)/${SDK_DIR}/hpl/port \ + $(TOP)/${SDK_DIR}/hri \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ # flash using bossac at least version 1.8 # can be found in arduino15/packages/arduino/tools/bossac/ -- cgit v1.3.1 From 1b97cec9957cfc06d3c2e4eab6d244e8a98aa271 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 11:19:44 +0700 Subject: fix missing linker entry with cmake for broadcom family --- hw/bsp/broadcom_32bit/family.c | 38 +++++++++++++++----------------------- hw/bsp/broadcom_32bit/family.cmake | 27 ++++++++++++++------------- hw/bsp/broadcom_64bit/family.c | 38 +++++++++++++++----------------------- hw/bsp/broadcom_64bit/family.cmake | 31 ++++++++++++++++++------------- hw/bsp/broadcom_64bit/family.mk | 1 + 5 files changed, 63 insertions(+), 72 deletions(-) diff --git a/hw/bsp/broadcom_32bit/family.c b/hw/bsp/broadcom_32bit/family.c index 626565e34..0062e2e83 100644 --- a/hw/bsp/broadcom_32bit/family.c +++ b/hw/bsp/broadcom_32bit/family.c @@ -55,8 +55,7 @@ //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB_IRQHandler(void) -{ +void USB_IRQHandler(void) { tud_int_handler(0); } @@ -67,8 +66,7 @@ void USB_IRQHandler(void) //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ -void board_init(void) -{ +void board_init(void) { setup_mmu_flat_map(); init_caches(); @@ -108,24 +106,21 @@ void board_init(void) BP_EnableIRQs(); } -void board_led_write(bool state) -{ - gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return 0; } -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; return 0; } -int board_uart_write(void const * buf, int len) -{ +int board_uart_write(void const* buf, int len) { for (int i = 0; i < len; i++) { const char* cbuf = buf; while (!UART1->STAT_b.TX_READY) {} @@ -138,30 +133,27 @@ int board_uart_write(void const * buf, int len) return len; } -#if CFG_TUSB_OS == OPT_OS_NONE +#if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -void TIMER_1_IRQHandler(void) -{ +void TIMER_1_IRQHandler(void) { system_ticks++; SYSTMR->C1 += 977; SYSTMR->CS_b.M1 = 1; } -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } + #endif -void HardFault_Handler (void) -{ +void HardFault_Handler(void) { // asm("bkpt"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. -void _init(void) -{ +void _init(void) { } diff --git a/hw/bsp/broadcom_32bit/family.cmake b/hw/bsp/broadcom_32bit/family.cmake index 223c85e48..6205d4e1b 100644 --- a/hw/bsp/broadcom_32bit/family.cmake +++ b/hw/bsp/broadcom_32bit/family.cmake @@ -1,6 +1,6 @@ include_guard() -set(MCU_DIR ${TOP}/hw/mcu/broadcom) +set(SDK_DIR ${TOP}/hw/mcu/broadcom) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) @@ -21,22 +21,20 @@ function(add_board_target BOARD_TARGET) endif () if (NOT DEFINED LD_FILE_GNU) - set(LD_FILE_GNU ${MCU_DIR}/broadcom/link.ld) + set(LD_FILE_GNU ${SDK_DIR}/broadcom/link.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) - if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) - set(STARTUP_FILE_GNU ${MCU_DIR}/broadcom/boot.s) - endif () + set(STARTUP_FILE_GNU ${SDK_DIR}/broadcom/boot.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) add_library(${BOARD_TARGET} STATIC - ${MCU_DIR}/broadcom/gen/interrupt_handlers.c - ${MCU_DIR}/broadcom/gpio.c - ${MCU_DIR}/broadcom/interrupts.c - ${MCU_DIR}/broadcom/mmu.c - ${MCU_DIR}/broadcom/caches.c - ${MCU_DIR}/broadcom/vcmailbox.c + ${SDK_DIR}/broadcom/gen/interrupt_handlers.c + ${SDK_DIR}/broadcom/gpio.c + ${SDK_DIR}/broadcom/interrupts.c + ${SDK_DIR}/broadcom/mmu.c + ${SDK_DIR}/broadcom/caches.c + ${SDK_DIR}/broadcom/vcmailbox.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_compile_options(${BOARD_TARGET} PUBLIC @@ -47,7 +45,7 @@ function(add_board_target BOARD_TARGET) -std=c17 ) target_include_directories(${BOARD_TARGET} PUBLIC - ${MCU_DIR} + ${SDK_DIR} ) update_board(${BOARD_TARGET}) @@ -55,11 +53,14 @@ function(add_board_target BOARD_TARGET) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" - -nostdlib -nostartfiles + "LINKER:--entry=_start" + --specs=nosys.specs + -nostartfiles ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" + "LINKER:--entry=_start" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC diff --git a/hw/bsp/broadcom_64bit/family.c b/hw/bsp/broadcom_64bit/family.c index 626565e34..0062e2e83 100644 --- a/hw/bsp/broadcom_64bit/family.c +++ b/hw/bsp/broadcom_64bit/family.c @@ -55,8 +55,7 @@ //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB_IRQHandler(void) -{ +void USB_IRQHandler(void) { tud_int_handler(0); } @@ -67,8 +66,7 @@ void USB_IRQHandler(void) //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ -void board_init(void) -{ +void board_init(void) { setup_mmu_flat_map(); init_caches(); @@ -108,24 +106,21 @@ void board_init(void) BP_EnableIRQs(); } -void board_led_write(bool state) -{ - gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return 0; } -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; return 0; } -int board_uart_write(void const * buf, int len) -{ +int board_uart_write(void const* buf, int len) { for (int i = 0; i < len; i++) { const char* cbuf = buf; while (!UART1->STAT_b.TX_READY) {} @@ -138,30 +133,27 @@ int board_uart_write(void const * buf, int len) return len; } -#if CFG_TUSB_OS == OPT_OS_NONE +#if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -void TIMER_1_IRQHandler(void) -{ +void TIMER_1_IRQHandler(void) { system_ticks++; SYSTMR->C1 += 977; SYSTMR->CS_b.M1 = 1; } -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } + #endif -void HardFault_Handler (void) -{ +void HardFault_Handler(void) { // asm("bkpt"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. -void _init(void) -{ +void _init(void) { } diff --git a/hw/bsp/broadcom_64bit/family.cmake b/hw/bsp/broadcom_64bit/family.cmake index b534e29be..f373dc633 100644 --- a/hw/bsp/broadcom_64bit/family.cmake +++ b/hw/bsp/broadcom_64bit/family.cmake @@ -1,6 +1,7 @@ include_guard() -set(MCU_DIR ${TOP}/hw/mcu/broadcom) +set(SDK_DIR ${TOP}/hw/mcu/broadcom) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) @@ -21,22 +22,20 @@ function(add_board_target BOARD_TARGET) endif () if (NOT DEFINED LD_FILE_GNU) - set(LD_FILE_GNU ${MCU_DIR}/broadcom/link8.ld) + set(LD_FILE_GNU ${SDK_DIR}/broadcom/link8.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) - if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) - set(STARTUP_FILE_GNU ${MCU_DIR}/broadcom/boot8.s) - endif () + set(STARTUP_FILE_GNU ${SDK_DIR}/broadcom/boot8.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) add_library(${BOARD_TARGET} STATIC - ${MCU_DIR}/broadcom/gen/interrupt_handlers.c - ${MCU_DIR}/broadcom/gpio.c - ${MCU_DIR}/broadcom/interrupts.c - ${MCU_DIR}/broadcom/mmu.c - ${MCU_DIR}/broadcom/caches.c - ${MCU_DIR}/broadcom/vcmailbox.c + ${SDK_DIR}/broadcom/gen/interrupt_handlers.c + ${SDK_DIR}/broadcom/gpio.c + ${SDK_DIR}/broadcom/interrupts.c + ${SDK_DIR}/broadcom/mmu.c + ${SDK_DIR}/broadcom/caches.c + ${SDK_DIR}/broadcom/vcmailbox.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_compile_options(${BOARD_TARGET} PUBLIC @@ -50,19 +49,25 @@ function(add_board_target BOARD_TARGET) BCM_VERSION=${BCM_VERSION} ) target_include_directories(${BOARD_TARGET} PUBLIC - ${MCU_DIR} + ${SDK_DIR} + ${CMSIS_5}/CMSIS/Core_A/Include ) update_board(${BOARD_TARGET}) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") +# target_compile_options(${BOARD_TARGET} PUBLIC +# ) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" - -nostdlib -nostartfiles + "LINKER:--entry=_start" + --specs=nosys.specs + -nostartfiles ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" + "LINKER:--entry=_start" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC diff --git a/hw/bsp/broadcom_64bit/family.mk b/hw/bsp/broadcom_64bit/family.mk index 80eff1d36..89f798f19 100644 --- a/hw/bsp/broadcom_64bit/family.mk +++ b/hw/bsp/broadcom_64bit/family.mk @@ -7,6 +7,7 @@ CFLAGS += \ -ffreestanding \ -nostdlib \ -nostartfiles \ + --specs=nosys.specs \ -mgeneral-regs-only \ -std=c17 -- cgit v1.3.1 From 6524e26e627999439465863e6bf87719e869ead8 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 11:39:42 +0700 Subject: add cmake for stm32wb --- .github/workflows/build_arm.yml | 9 +- .github/workflows/build_cmake.yml | 4 +- hw/bsp/stm32f0/family.cmake | 92 +++++++++-------- hw/bsp/stm32f1/family.cmake | 92 +++++++++-------- hw/bsp/stm32f2/family.cmake | 92 +++++++++-------- hw/bsp/stm32f3/family.cmake | 88 ++++++++-------- hw/bsp/stm32f7/family.cmake | 96 ++++++++--------- hw/bsp/stm32h7/family.cmake | 100 +++++++++--------- hw/bsp/stm32l0/family.cmake | 94 ++++++++--------- hw/bsp/stm32l4/family.cmake | 94 ++++++++--------- hw/bsp/stm32u5/family.cmake | 96 ++++++++--------- hw/bsp/stm32wb/boards/stm32wb55nucleo/board.cmake | 10 ++ hw/bsp/stm32wb/boards/stm32wb55nucleo/board.mk | 6 +- hw/bsp/stm32wb/family.c | 72 ++++++------- hw/bsp/stm32wb/family.cmake | 119 ++++++++++++++++++++++ hw/bsp/stm32wb/family.mk | 22 ++-- 16 files changed, 611 insertions(+), 475 deletions(-) create mode 100644 hw/bsp/stm32wb/boards/stm32wb55nucleo/board.cmake create mode 100644 hw/bsp/stm32wb/family.cmake diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 12e6615ea..55c4bd204 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -35,13 +35,8 @@ jobs: matrix: family: # Alphabetical order - - 'broadcom_32bit' - - 'kinetis_k32l2' - - 'lpc11 lpc13 lpc15' - - 'lpc51' - - 'mm32 msp432e4' - - 'samd11 same5x saml2x' - - 'stm32l0 stm32wb' + - 'mm32' + - 'samd11 same5x' - 'tm4c123 xmc4000' steps: - name: Setup Python diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index cbe36ae79..38df38730 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -48,8 +48,7 @@ jobs: - 'nrf' - 'ra' - 'rp2040' - - 'samd21' - - 'samd51' + - 'samd21 saml2x samd51' - 'stm32f0' - 'stm32f1' - 'stm32f2' @@ -62,6 +61,7 @@ jobs: - 'stm32h7' - 'stm32l4' - 'stm32u5' + - 'stm32wb' steps: - name: Setup Python uses: actions/setup-python@v5 diff --git a/hw/bsp/stm32f0/family.cmake b/hw/bsp/stm32f0/family.cmake index 427c56671..0af200dd5 100644 --- a/hw/bsp/stm32f0/family.cmake +++ b/hw/bsp/stm32f0/family.cmake @@ -22,54 +22,56 @@ set(FAMILY_MCUS STM32F0 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - - set(LD_FILE_Clang ${LD_FILE_GNU}) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + if (TARGET ${BOARD_TARGET}) + return() + endif() + + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + #target_compile_options(${BOARD_TARGET} PUBLIC) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_EXAMPLE_MSC_READONLY + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" ) - #target_compile_options(${BOARD_TARGET} PUBLIC) - target_compile_definitions(${BOARD_TARGET} PUBLIC - CFG_EXAMPLE_MSC_READONLY + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" ) - - update_board(${BOARD_TARGET}) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - --specs=nosys.specs --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_Clang}" - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () endif () endfunction() diff --git a/hw/bsp/stm32f1/family.cmake b/hw/bsp/stm32f1/family.cmake index cf7e8e9b1..e8cc4db1f 100644 --- a/hw/bsp/stm32f1/family.cmake +++ b/hw/bsp/stm32f1/family.cmake @@ -22,53 +22,55 @@ set(FAMILY_MCUS STM32F1 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - - set(LD_FILE_Clang ${LD_FILE_GNU}) - if (NOT DEFINED LD_FILE_IAR) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - endif () - - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + if (TARGET ${BOARD_TARGET}) + return() + endif() + +# Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + + set(LD_FILE_Clang ${LD_FILE_GNU}) + if (NOT DEFINED LD_FILE_IAR) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + endif () + + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + #target_compile_options(${BOARD_TARGET} PUBLIC) + #target_compile_definitions(${BOARD_TARGET} PUBLIC) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" ) - #target_compile_options(${BOARD_TARGET} PUBLIC) - #target_compile_definitions(${BOARD_TARGET} PUBLIC) - - update_board(${BOARD_TARGET}) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - --specs=nosys.specs --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_Clang}" - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () endif () endfunction() diff --git a/hw/bsp/stm32f2/family.cmake b/hw/bsp/stm32f2/family.cmake index 862680bce..a01ebef5c 100644 --- a/hw/bsp/stm32f2/family.cmake +++ b/hw/bsp/stm32f2/family.cmake @@ -22,53 +22,55 @@ set(FAMILY_MCUS STM32F2 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - - set(LD_FILE_Clang ${LD_FILE_GNU}) - if (NOT DEFINED LD_FILE_IAR) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - endif () - - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + if (TARGET ${BOARD_TARGET}) + return() + endif() + + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + + set(LD_FILE_Clang ${LD_FILE_GNU}) + if (NOT DEFINED LD_FILE_IAR) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + endif () + + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + #target_compile_options(${BOARD_TARGET} PUBLIC) + #target_compile_definitions(${BOARD_TARGET} PUBLIC) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" ) - #target_compile_options(${BOARD_TARGET} PUBLIC) - #target_compile_definitions(${BOARD_TARGET} PUBLIC) - - update_board(${BOARD_TARGET}) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - --specs=nosys.specs --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_Clang}" - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () endif () endfunction() diff --git a/hw/bsp/stm32f3/family.cmake b/hw/bsp/stm32f3/family.cmake index 0a28e480b..dbba1e658 100644 --- a/hw/bsp/stm32f3/family.cmake +++ b/hw/bsp/stm32f3/family.cmake @@ -22,51 +22,53 @@ set(FAMILY_MCUS STM32F3 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - - set(LD_FILE_Clang ${LD_FILE_GNU}) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + if (TARGET ${BOARD_TARGET}) + return() + endif() + + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + #target_compile_options(${BOARD_TARGET} PUBLIC) + #target_compile_definitions(${BOARD_TARGET} PUBLIC) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" ) - #target_compile_options(${BOARD_TARGET} PUBLIC) - #target_compile_definitions(${BOARD_TARGET} PUBLIC) - - update_board(${BOARD_TARGET}) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - --specs=nosys.specs --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_Clang}" - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () endif () endfunction() diff --git a/hw/bsp/stm32f7/family.cmake b/hw/bsp/stm32f7/family.cmake index 17e632c40..938c2697a 100644 --- a/hw/bsp/stm32f7/family.cmake +++ b/hw/bsp/stm32f7/family.cmake @@ -22,55 +22,57 @@ set(FAMILY_MCUS STM32F7 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - - set(LD_FILE_Clang ${LD_FILE_GNU}) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + if (TARGET ${BOARD_TARGET}) + return() + endif() + + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + #target_compile_options(${BOARD_TARGET} PUBLIC) + #target_compile_definitions(${BOARD_TARGET} PUBLIC) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" ) - #target_compile_options(${BOARD_TARGET} PUBLIC) - #target_compile_definitions(${BOARD_TARGET} PUBLIC) - - update_board(${BOARD_TARGET}) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - --specs=nosys.specs --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_Clang}" - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () endif () endfunction() diff --git a/hw/bsp/stm32h7/family.cmake b/hw/bsp/stm32h7/family.cmake index e5ae6c69d..026c7c3df 100644 --- a/hw/bsp/stm32h7/family.cmake +++ b/hw/bsp/stm32h7/family.cmake @@ -22,57 +22,59 @@ set(FAMILY_MCUS STM32H7 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - - set(LD_FILE_Clang ${LD_FILE_GNU}) - if(NOT DEFINED LD_FILE_IAR) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - endif() - - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + if (TARGET ${BOARD_TARGET}) + return() + endif() + + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + + set(LD_FILE_Clang ${LD_FILE_GNU}) + if(NOT DEFINED LD_FILE_IAR) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + endif() + + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + #target_compile_options(${BOARD_TARGET} PUBLIC) + #target_compile_definitions(${BOARD_TARGET} PUBLIC) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" ) - #target_compile_options(${BOARD_TARGET} PUBLIC) - #target_compile_definitions(${BOARD_TARGET} PUBLIC) - - update_board(${BOARD_TARGET}) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - --specs=nosys.specs --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_Clang}" - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () endif () endfunction() diff --git a/hw/bsp/stm32l0/family.cmake b/hw/bsp/stm32l0/family.cmake index 962c55587..c04927585 100644 --- a/hw/bsp/stm32l0/family.cmake +++ b/hw/bsp/stm32l0/family.cmake @@ -22,55 +22,57 @@ set(FAMILY_MCUS STM32L0 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - - set(LD_FILE_Clang ${LD_FILE_GNU}) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + if (TARGET ${BOARD_TARGET}) + return() + endif() + + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + #target_compile_options(${BOARD_TARGET} PUBLIC) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_EXAMPLE_MSC_READONLY + CFG_EXAMPLE_VIDEO_READONLY + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" ) - #target_compile_options(${BOARD_TARGET} PUBLIC) - target_compile_definitions(${BOARD_TARGET} PUBLIC - CFG_EXAMPLE_MSC_READONLY - CFG_EXAMPLE_VIDEO_READONLY + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" ) - - update_board(${BOARD_TARGET}) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - --specs=nosys.specs --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_Clang}" - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () endif () endfunction() diff --git a/hw/bsp/stm32l4/family.cmake b/hw/bsp/stm32l4/family.cmake index c42b6a8d7..b6eae7c7f 100644 --- a/hw/bsp/stm32l4/family.cmake +++ b/hw/bsp/stm32l4/family.cmake @@ -22,55 +22,57 @@ set(FAMILY_MCUS STM32L4 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - - set(LD_FILE_Clang ${LD_FILE_GNU}) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc - ) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) # target_compile_options(${BOARD_TARGET} PUBLIC) # target_compile_definitions(${BOARD_TARGET} PUBLIC) - update_board(${BOARD_TARGET}) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - --specs=nosys.specs --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_Clang}" - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) endif () endfunction() diff --git a/hw/bsp/stm32u5/family.cmake b/hw/bsp/stm32u5/family.cmake index d3cb78abf..7402540b7 100644 --- a/hw/bsp/stm32u5/family.cmake +++ b/hw/bsp/stm32u5/family.cmake @@ -22,55 +22,57 @@ set(FAMILY_MCUS STM32U5 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - - string(REPLACE "stm32u" "STM32U" MCU_VARIANT_UPPER ${MCU_VARIANT}) - if (NOT DEFINED LD_FILE_GNU) - set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT_UPPER}_FLASH.ld) - endif () - set(LD_FILE_Clang ${LD_FILE_GNU}) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_icache.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + if (TARGET ${BOARD_TARGET}) + return() + endif() + + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + + string(REPLACE "stm32u" "STM32U" MCU_VARIANT_UPPER ${MCU_VARIANT}) + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT_UPPER}_FLASH.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_icache.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" ) - update_board(${BOARD_TARGET}) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - --specs=nosys.specs --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_Clang}" - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () endif () endfunction() diff --git a/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.cmake b/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.cmake new file mode 100644 index 000000000..5512aa2ee --- /dev/null +++ b/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.cmake @@ -0,0 +1,10 @@ +set(MCU_VARIANT stm32wb55xx) +set(JLINK_DEVICE STM32WB55RG) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/stm32wb55xx_flash_cm4.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32WB55xx + ) +endfunction() diff --git a/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.mk b/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.mk index d6adc6b63..009883f30 100644 --- a/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.mk +++ b/hw/bsp/stm32wb/boards/stm32wb55nucleo/board.mk @@ -1,9 +1,7 @@ +MCU_VARIANT = stm32wb55xx + CFLAGS += \ -DSTM32WB55xx -LD_FILE = $(BOARD_PATH)/stm32wb55xx_flash_cm4.ld - -SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32wb55xx_cm4.s - # For flash-jlink target JLINK_DEVICE = STM32WB55RG diff --git a/hw/bsp/stm32wb/family.c b/hw/bsp/stm32wb/family.c index d483c95b7..1dc789407 100644 --- a/hw/bsp/stm32wb/family.c +++ b/hw/bsp/stm32wb/family.c @@ -31,13 +31,11 @@ //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB_HP_IRQHandler(void) -{ +void USB_HP_IRQHandler(void) { tud_int_handler(0); } -void USB_LP_IRQHandler(void) -{ +void USB_LP_IRQHandler(void) { tud_int_handler(0); } @@ -46,8 +44,7 @@ void USB_LP_IRQHandler(void) //--------------------------------------------------------------------+ UART_HandleTypeDef UartHandle; -void board_init(void) -{ +void board_init(void) { board_clock_init(); // Enable All GPIOs clocks @@ -71,7 +68,7 @@ void board_init(void) NVIC_SetPriority(USB_LP_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif - GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitTypeDef GPIO_InitStruct; // LED GPIO_InitStruct.Pin = LED_PIN; @@ -102,22 +99,22 @@ void board_init(void) #ifdef UART_DEV // UART - GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = UART_GPIO_AF; HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); - UartHandle = (UART_HandleTypeDef){ - .Instance = UART_DEV, - .Init.BaudRate = CFG_BOARD_UART_BAUDRATE, - .Init.WordLength = UART_WORDLENGTH_8B, - .Init.StopBits = UART_STOPBITS_1, - .Init.Parity = UART_PARITY_NONE, - .Init.HwFlowCtl = UART_HWCONTROL_NONE, - .Init.Mode = UART_MODE_TX_RX, - .Init.OverSampling = UART_OVERSAMPLING_16 + UartHandle = (UART_HandleTypeDef) { + .Instance = UART_DEV, + .Init.BaudRate = CFG_BOARD_UART_BAUDRATE, + .Init.WordLength = UART_WORDLENGTH_8B, + .Init.StopBits = UART_STOPBITS_1, + .Init.Parity = UART_PARITY_NONE, + .Init.HwFlowCtl = UART_HWCONTROL_NONE, + .Init.Mode = UART_MODE_TX_RX, + .Init.OverSampling = UART_OVERSAMPLING_16 }; HAL_UART_Init(&UartHandle); #endif @@ -138,26 +135,23 @@ void board_init(void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ - HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; return 0; } -int board_uart_write(void const * buf, int len) -{ +int board_uart_write(void const* buf, int len) { #ifdef UART_DEV - HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); + HAL_UART_Transmit(&UartHandle, (uint8_t*) (uintptr_t) buf, len, 0xffff); return len; #else (void) buf; (void) len; (void) UartHandle; @@ -165,28 +159,26 @@ int board_uart_write(void const * buf, int len) #endif } -#if CFG_TUSB_OS == OPT_OS_NONE +#if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -void SysTick_Handler (void) -{ + +void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } + #endif -void HardFault_Handler (void) -{ +void HardFault_Handler(void) { asm("bkpt"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. -void _init(void) -{ +void _init(void) { } diff --git a/hw/bsp/stm32wb/family.cmake b/hw/bsp/stm32wb/family.cmake new file mode 100644 index 000000000..071797c20 --- /dev/null +++ b/hw/bsp/stm32wb/family.cmake @@ -0,0 +1,119 @@ +include_guard() + +set(ST_FAMILY wb) +set(ST_PREFIX stm32${ST_FAMILY}xx) + +set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) +set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS STM32WB CACHE INTERNAL "") + + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}_cm4.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}_cm4.s) + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/linker/${MCU_VARIANT}_flash_cm4.ld) + endif() + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash_cm4.icf) + + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) +# target_compile_options(${BOARD_TARGET} PUBLIC) +# target_compile_definitions(${BOARD_TARGET} PUBLIC) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_${FAMILY_MCUS} ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_stlink(${TARGET}) + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/stm32wb/family.mk b/hw/bsp/stm32wb/family.mk index 287b58ce5..de8372eea 100644 --- a/hw/bsp/stm32wb/family.mk +++ b/hw/bsp/stm32wb/family.mk @@ -1,7 +1,7 @@ UF2_FAMILY_ID = 0x70d16653 ST_FAMILY = wb -DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver +ST_PREFIX = stm32${ST_FAMILY}xx ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver @@ -16,18 +16,22 @@ CFLAGS += \ # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=cast-align -Wno-unused-parameter +LD_FILE ?= ${ST_CMSIS}/Source/Templates/gcc/linker/${MCU_VARIANT}_flash_cm4.ld + LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ - $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c + $(ST_CMSIS)/Source/Templates/system_${ST_PREFIX}.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pwr_ex.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_uart.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_gpio.c + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_${MCU_VARIANT}_cm4.s INC += \ $(TOP)/$(BOARD_PATH) \ -- cgit v1.3.1 From 43f4317a97d51eec2fdf90bcd545474fe97c77f3 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 12:21:02 +0700 Subject: add missing FreeRTOSConfig.h --- hw/bsp/saml2x/FreeRTOSConfig/FreeRTOSConfig.h | 149 +++++++++++++++++++++++++ hw/bsp/stm32wb/FreeRTOSConfig/FreeRTOSConfig.h | 149 +++++++++++++++++++++++++ 2 files changed, 298 insertions(+) create mode 100644 hw/bsp/saml2x/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/stm32wb/FreeRTOSConfig/FreeRTOSConfig.h diff --git a/hw/bsp/saml2x/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/saml2x/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..4aa0f8cca --- /dev/null +++ b/hw/bsp/saml2x/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "sam.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 2 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< Date: Fri, 3 May 2024 12:45:41 +0700 Subject: - add cmake to samd11 - build_cmake.py always build with -DCMAKE_BUILD_TYPE=MinSizeRel --- .github/workflows/build_cmake.yml | 6 +- .github/workflows/build_iar.yml | 2 +- hw/bsp/samd11/FreeRTOSConfig/FreeRTOSConfig.h | 153 +++++++++++++++++++++ hw/bsp/samd11/boards/cynthion_d11/board.cmake | 14 ++ hw/bsp/samd11/boards/cynthion_d11/board.mk | 2 +- hw/bsp/samd11/boards/cynthion_d11/cynthion_d11.ld | 146 ++++++++++++++++++++ .../boards/cynthion_d11/samd11d14am_flash.ld | 144 ------------------- hw/bsp/samd11/boards/samd11_xplained/board.cmake | 8 ++ .../boards/samd11_xplained/samd11d14am_flash.ld | 2 + hw/bsp/samd11/family.c | 16 ++- hw/bsp/samd11/family.cmake | 116 ++++++++++++++++ hw/bsp/samd11/family.mk | 6 +- hw/bsp/samd21/FreeRTOSConfig/FreeRTOSConfig.h | 6 +- hw/bsp/saml2x/FreeRTOSConfig/FreeRTOSConfig.h | 6 +- hw/bsp/stm32wb/FreeRTOSConfig/FreeRTOSConfig.h | 6 +- tools/build_cmake.py | 2 +- 16 files changed, 476 insertions(+), 159 deletions(-) create mode 100644 hw/bsp/samd11/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/samd11/boards/cynthion_d11/board.cmake create mode 100644 hw/bsp/samd11/boards/cynthion_d11/cynthion_d11.ld delete mode 100644 hw/bsp/samd11/boards/cynthion_d11/samd11d14am_flash.ld create mode 100644 hw/bsp/samd11/boards/samd11_xplained/board.cmake create mode 100644 hw/bsp/samd11/family.cmake diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 38df38730..be24c09d4 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -90,7 +90,7 @@ jobs: python3 tools/get_deps.py ${{ matrix.family }} - name: Build - run: python tools/build_cmake.py ${{ matrix.family }} -DCMAKE_BUILD_TYPE=MinSizeRel + run: python tools/build_cmake.py ${{ matrix.family }} env: PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk @@ -191,7 +191,7 @@ jobs: python3 tools/get_deps.py ${{ matrix.family }} - name: Build - run: python tools/build_cmake.py ${{ matrix.family }} -DTOOLCHAIN=clang -DCMAKE_BUILD_TYPE=MinSizeRel + run: python tools/build_cmake.py ${{ matrix.family }} -DTOOLCHAIN=clang env: PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk @@ -239,7 +239,7 @@ jobs: python3 tools/get_deps.py ${{ matrix.family }} - name: Build - run: python tools/build_cmake.py ${{ matrix.family }} -DCMAKE_BUILD_TYPE=MinSizeRel + run: python tools/build_cmake.py ${{ matrix.family }} # --------------------------------------- # Hardware in the loop (HIL) diff --git a/.github/workflows/build_iar.yml b/.github/workflows/build_iar.yml index 499349904..6b1493a97 100644 --- a/.github/workflows/build_iar.yml +++ b/.github/workflows/build_iar.yml @@ -52,7 +52,7 @@ jobs: run: python3 tools/get_deps.py ${{ matrix.family }} - name: Build - run: python3 tools/build_cmake.py ${{ matrix.family }} -DTOOLCHAIN=iar -DCMAKE_BUILD_TYPE=MinSizeRel + run: python3 tools/build_cmake.py ${{ matrix.family }} -DTOOLCHAIN=iar - name: Test on actual hardware (hardware in the loop) run: | diff --git a/hw/bsp/samd11/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/samd11/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..6c9ecae2d --- /dev/null +++ b/hw/bsp/samd11/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,153 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "sam.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 2 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + end = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; +} diff --git a/hw/bsp/samd11/boards/cynthion_d11/samd11d14am_flash.ld b/hw/bsp/samd11/boards/cynthion_d11/samd11d14am_flash.ld deleted file mode 100644 index 57e7f8904..000000000 --- a/hw/bsp/samd11/boards/cynthion_d11/samd11d14am_flash.ld +++ /dev/null @@ -1,144 +0,0 @@ -/** - * \file - * - * \brief Linker script for running in internal FLASH on the SAMD11D14AM - * - * Copyright (c) 2018 Microchip Technology Inc. - * - * \asf_license_start - * - * \page License - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the Licence at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * \asf_license_stop - * - */ - - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -SEARCH_DIR(.) - -/* Memory Spaces Definitions */ -MEMORY -{ - rom (rx) : ORIGIN = 0x00000000 + BOOTLOADER_SIZE, LENGTH = 0x00004000 - BOOTLOADER_SIZE - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00001000 -} - -/* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x400; - -/* Section Definitions */ -SECTIONS -{ - .text : - { - . = ALIGN(4); - _sfixed = .; - KEEP(*(.vectors .vectors.*)) - *(.text .text.* .gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) - *(.rodata .rodata* .gnu.linkonce.r.*) - *(.ARM.extab* .gnu.linkonce.armextab.*) - - /* Support C constructors, and C destructors in both user code - and the C library. This also provides support for C++ code. */ - . = ALIGN(4); - KEEP(*(.init)) - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - - . = ALIGN(4); - _efixed = .; /* End of text section */ - } > rom - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - PROVIDE_HIDDEN (__exidx_start = .); - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > rom - PROVIDE_HIDDEN (__exidx_end = .); - - . = ALIGN(4); - _etext = .; - - .relocate : AT (_etext) - { - . = ALIGN(4); - _srelocate = .; - *(.ramfunc .ramfunc.*); - *(.data .data.*); - . = ALIGN(4); - _erelocate = .; - } > ram - - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = . ; - _szero = .; - *(.bss .bss.*) - *(COMMON) - . = ALIGN(4); - _ebss = . ; - _ezero = .; - end = .; - } > ram - - /* stack section */ - .stack (NOLOAD): - { - . = ALIGN(8); - _sstack = .; - . = . + STACK_SIZE; - . = ALIGN(8); - _estack = .; - } > ram - - . = ALIGN(4); - _end = . ; -} diff --git a/hw/bsp/samd11/boards/samd11_xplained/board.cmake b/hw/bsp/samd11/boards/samd11_xplained/board.cmake new file mode 100644 index 000000000..13a6e3af7 --- /dev/null +++ b/hw/bsp/samd11/boards/samd11_xplained/board.cmake @@ -0,0 +1,8 @@ +set(JLINK_DEVICE ATSAMD11D14) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/samd11d14am_flash.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD11D14AM__ + ) +endfunction() diff --git a/hw/bsp/samd11/boards/samd11_xplained/samd11d14am_flash.ld b/hw/bsp/samd11/boards/samd11_xplained/samd11d14am_flash.ld index 75d880f62..3a35914e2 100644 --- a/hw/bsp/samd11/boards/samd11_xplained/samd11d14am_flash.ld +++ b/hw/bsp/samd11/boards/samd11_xplained/samd11d14am_flash.ld @@ -32,6 +32,8 @@ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) +ENTRY(Reset_Handler) + /* Memory Spaces Definitions */ MEMORY { diff --git a/hw/bsp/samd11/family.c b/hw/bsp/samd11/family.c index e15f8c91c..a6588805a 100644 --- a/hw/bsp/samd11/family.c +++ b/hw/bsp/samd11/family.c @@ -25,8 +25,12 @@ */ #include "sam.h" -#include "bsp/board_api.h" -#include "board.h" + +// Suppress warning caused by mcu driver +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif #include "hal/include/hal_gpio.h" #include "hal/include/hal_init.h" @@ -36,6 +40,14 @@ #include "hpl_pm_config.h" #include "hpl/pm/hpl_pm_base.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#include "bsp/board_api.h" +#include "board.h" + + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ diff --git a/hw/bsp/samd11/family.cmake b/hw/bsp/samd11/family.cmake new file mode 100644 index 000000000..33b309873 --- /dev/null +++ b/hw/bsp/samd11/family.cmake @@ -0,0 +1,116 @@ +include_guard() + +set(MCU_VARIANT samd11) +set(SDK_DIR ${TOP}/hw/mcu/microchip/${MCU_VARIANT}) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS SAMD11 CACHE INTERNAL "") +set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -f target/at91samdXX.cfg") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + set(LD_FILE_Clang ${LD_FILE_GNU}) + if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) + message(FATAL_ERROR "LD_FILE_${CMAKE_C_COMPILER_ID} not defined") + endif () + + set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_${MCU_VARIANT}.c) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/gcc/system_${MCU_VARIANT}.c + ${SDK_DIR}/hal/src/hal_atomic.c + ${SDK_DIR}/hpl/gclk/hpl_gclk.c + ${SDK_DIR}/hpl/pm/hpl_pm.c + ${SDK_DIR}/hpl/sysctrl/hpl_sysctrl.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR} + ${SDK_DIR}/config + ${SDK_DIR}/include + ${SDK_DIR}/hal/include + ${SDK_DIR}/hal/utils/include + ${SDK_DIR}/hpl/pm + ${SDK_DIR}/hpl/port + ${SDK_DIR}/hri + ${CMSIS_5}/CMSIS/Core/Include + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CONF_DFLL_OVERWRITE_CALIBRATION=0 + OSC32K_OVERWRITE_CALIBRATION=0 + CFG_EXAMPLE_MSC_READONLY + CFG_EXAMPLE_VIDEO_READONLY + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_SAMD11 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/microchip/samd/dcd_samd.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_jlink(${TARGET}) + #family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) +endfunction() diff --git a/hw/bsp/samd11/family.mk b/hw/bsp/samd11/family.mk index 38430f017..c41a0dd37 100644 --- a/hw/bsp/samd11/family.mk +++ b/hw/bsp/samd11/family.mk @@ -1,5 +1,3 @@ -DEPS_SUBMODULES += hw/mcu/microchip - include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus @@ -22,12 +20,12 @@ LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ - hw/mcu/microchip/samd11/gcc/gcc/startup_samd11.c \ hw/mcu/microchip/samd11/gcc/system_samd11.c \ + hw/mcu/microchip/samd11/gcc/gcc/startup_samd11.c \ + hw/mcu/microchip/samd11/hal/src/hal_atomic.c \ hw/mcu/microchip/samd11/hpl/gclk/hpl_gclk.c \ hw/mcu/microchip/samd11/hpl/pm/hpl_pm.c \ hw/mcu/microchip/samd11/hpl/sysctrl/hpl_sysctrl.c \ - hw/mcu/microchip/samd11/hal/src/hal_atomic.c INC += \ $(TOP)/$(BOARD_PATH) \ diff --git a/hw/bsp/samd21/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/samd21/FreeRTOSConfig/FreeRTOSConfig.h index 4aa0f8cca..6c9ecae2d 100644 --- a/hw/bsp/samd21/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/samd21/FreeRTOSConfig/FreeRTOSConfig.h @@ -49,7 +49,11 @@ /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 -#define configENABLE_FPU 1 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) diff --git a/hw/bsp/saml2x/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/saml2x/FreeRTOSConfig/FreeRTOSConfig.h index 4aa0f8cca..6c9ecae2d 100644 --- a/hw/bsp/saml2x/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/saml2x/FreeRTOSConfig/FreeRTOSConfig.h @@ -49,7 +49,11 @@ /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 -#define configENABLE_FPU 1 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) diff --git a/hw/bsp/stm32wb/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32wb/FreeRTOSConfig/FreeRTOSConfig.h index 4c05c93d4..6ad115f60 100644 --- a/hw/bsp/stm32wb/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/stm32wb/FreeRTOSConfig/FreeRTOSConfig.h @@ -49,7 +49,11 @@ /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 -#define configENABLE_FPU 1 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) diff --git a/tools/build_cmake.py b/tools/build_cmake.py index e539b9f94..2eda3f90f 100644 --- a/tools/build_cmake.py +++ b/tools/build_cmake.py @@ -36,7 +36,7 @@ def build_family(family, cmake_option): # Generate build r = subprocess.run(f"cmake examples -B {build_dir} -G \"Ninja\" -DFAMILY={family} -DBOARD" - f"={board} {cmake_option}", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + f"={board} -DCMAKE_BUILD_TYPE=MinSizeRel {cmake_option}", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) # Build if r.returncode == 0: -- cgit v1.3.1 From 4b86b492603cbb869b7cbcad704f92009b6c364f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 15:15:27 +0700 Subject: merge samd51 and same5x --- .github/workflows/build_arm.yml | 2 +- .github/workflows/build_cmake.yml | 2 +- hw/bsp/samd11/family.cmake | 8 +- hw/bsp/samd51/boards/d5035_01/board.cmake | 13 + hw/bsp/samd51/boards/d5035_01/board.h | 198 ++++++++++++ hw/bsp/samd51/boards/d5035_01/board.mk | 21 ++ hw/bsp/samd51/boards/d5035_01/same51j19a_flash.ld | 166 ++++++++++ .../samd51/boards/feather_m4_express/board.cmake | 2 + hw/bsp/samd51/boards/feather_m4_express/board.mk | 2 + hw/bsp/samd51/boards/itsybitsy_m4/board.cmake | 2 + hw/bsp/samd51/boards/itsybitsy_m4/board.mk | 2 + hw/bsp/samd51/boards/metro_m4_express/board.cmake | 2 + hw/bsp/samd51/boards/metro_m4_express/board.mk | 2 + hw/bsp/samd51/boards/pybadge/board.cmake | 2 + hw/bsp/samd51/boards/pybadge/board.mk | 2 + hw/bsp/samd51/boards/pyportal/board.cmake | 2 + hw/bsp/samd51/boards/pyportal/board.mk | 2 + hw/bsp/samd51/boards/same54_xplained/board.cmake | 10 + hw/bsp/samd51/boards/same54_xplained/board.h | 50 +++ hw/bsp/samd51/boards/same54_xplained/board.mk | 9 + .../boards/same54_xplained/same54p20a_flash.ld | 166 ++++++++++ .../boards/same54_xplained/same54p20a_sram.ld | 165 ++++++++++ hw/bsp/samd51/family.c | 57 +++- hw/bsp/samd51/family.cmake | 19 +- hw/bsp/samd51/family.mk | 35 +- hw/bsp/same5x/boards/d5035_01/board.mk | 21 -- hw/bsp/same5x/boards/d5035_01/d5035_01.c | 353 --------------------- hw/bsp/same5x/boards/d5035_01/same51j19a_flash.ld | 164 ---------- hw/bsp/same5x/boards/same54_xplained/board.mk | 12 - .../boards/same54_xplained/same54_xplained.c | 306 ------------------ .../boards/same54_xplained/same54p20a_flash.ld | 163 ---------- .../boards/same54_xplained/same54p20a_sram.ld | 162 ---------- hw/bsp/same5x/family.mk | 38 --- hw/bsp/saml2x/boards/atsaml21_xpro/board.cmake | 2 +- hw/bsp/saml2x/boards/atsaml21_xpro/board.mk | 2 +- hw/bsp/saml2x/boards/saml22_feather/board.cmake | 2 +- hw/bsp/saml2x/boards/saml22_feather/board.mk | 2 +- hw/bsp/saml2x/boards/sensorwatch_m0/board.cmake | 2 +- hw/bsp/saml2x/boards/sensorwatch_m0/board.mk | 2 +- hw/bsp/saml2x/family.cmake | 6 +- hw/bsp/saml2x/family.mk | 6 +- 41 files changed, 919 insertions(+), 1265 deletions(-) create mode 100644 hw/bsp/samd51/boards/d5035_01/board.cmake create mode 100644 hw/bsp/samd51/boards/d5035_01/board.h create mode 100644 hw/bsp/samd51/boards/d5035_01/board.mk create mode 100644 hw/bsp/samd51/boards/d5035_01/same51j19a_flash.ld create mode 100644 hw/bsp/samd51/boards/same54_xplained/board.cmake create mode 100644 hw/bsp/samd51/boards/same54_xplained/board.h create mode 100644 hw/bsp/samd51/boards/same54_xplained/board.mk create mode 100644 hw/bsp/samd51/boards/same54_xplained/same54p20a_flash.ld create mode 100644 hw/bsp/samd51/boards/same54_xplained/same54p20a_sram.ld delete mode 100644 hw/bsp/same5x/boards/d5035_01/board.mk delete mode 100644 hw/bsp/same5x/boards/d5035_01/d5035_01.c delete mode 100644 hw/bsp/same5x/boards/d5035_01/same51j19a_flash.ld delete mode 100644 hw/bsp/same5x/boards/same54_xplained/board.mk delete mode 100644 hw/bsp/same5x/boards/same54_xplained/same54_xplained.c delete mode 100644 hw/bsp/same5x/boards/same54_xplained/same54p20a_flash.ld delete mode 100644 hw/bsp/same5x/boards/same54_xplained/same54p20a_sram.ld delete mode 100644 hw/bsp/same5x/family.mk diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 55c4bd204..40dc77593 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -36,7 +36,7 @@ jobs: family: # Alphabetical order - 'mm32' - - 'samd11 same5x' + - 'same5x' - 'tm4c123 xmc4000' steps: - name: Setup Python diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index be24c09d4..75ce707aa 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -48,7 +48,7 @@ jobs: - 'nrf' - 'ra' - 'rp2040' - - 'samd21 saml2x samd51' + - 'samd11 samd21 saml2x samd51' - 'stm32f0' - 'stm32f1' - 'stm32f2' diff --git a/hw/bsp/samd11/family.cmake b/hw/bsp/samd11/family.cmake index 33b309873..c0d1f5a7e 100644 --- a/hw/bsp/samd11/family.cmake +++ b/hw/bsp/samd11/family.cmake @@ -1,7 +1,7 @@ include_guard() -set(MCU_VARIANT samd11) -set(SDK_DIR ${TOP}/hw/mcu/microchip/${MCU_VARIANT}) +set(SAM_FAMILY samd11) +set(SDK_DIR ${TOP}/hw/mcu/microchip/${SAM_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) @@ -27,11 +27,11 @@ function(add_board_target BOARD_TARGET) message(FATAL_ERROR "LD_FILE_${CMAKE_C_COMPILER_ID} not defined") endif () - set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_${MCU_VARIANT}.c) + set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_${SAM_FAMILY}.c) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/gcc/system_${MCU_VARIANT}.c + ${SDK_DIR}/gcc/system_${SAM_FAMILY}.c ${SDK_DIR}/hal/src/hal_atomic.c ${SDK_DIR}/hpl/gclk/hpl_gclk.c ${SDK_DIR}/hpl/pm/hpl_pm.c diff --git a/hw/bsp/samd51/boards/d5035_01/board.cmake b/hw/bsp/samd51/boards/d5035_01/board.cmake new file mode 100644 index 000000000..adf4f6a6d --- /dev/null +++ b/hw/bsp/samd51/boards/d5035_01/board.cmake @@ -0,0 +1,13 @@ +set(SAM_FAMILY same51) + +set(JLINK_DEVICE ATSAME51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/same51j19a_flash.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAME51J19A__ + SVC_Handler=SVCall_Handler + CONF_CPU_FREQUENCY=80000000 + CONF_GCLK_USB_FREQUENCY=48000000 + ) +endfunction() diff --git a/hw/bsp/samd51/boards/d5035_01/board.h b/hw/bsp/samd51/boards/d5035_01/board.h new file mode 100644 index 000000000..2cf59f5d1 --- /dev/null +++ b/hw/bsp/samd51/boards/d5035_01/board.h @@ -0,0 +1,198 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PIN PIN_PA02 +#define LED_STATE_ON 1 + +// Button: no button + +// UART: HWREV < 3: SERCOM5 on PB02, otherwise SERCOM0 on PA08 +// XTAL configure is also different for HWREV as well + +#if 0 +static inline void init_clock(void) { + /* AUTOWS is enabled by default in REG_NVMCTRL_CTRLA - no need to change the number of wait states when changing the core clock */ +#if HWREV == 1 + /* configure XOSC1 for a 16MHz crystal connected to XIN1/XOUT1 */ + OSCCTRL->XOSCCTRL[1].reg = + OSCCTRL_XOSCCTRL_STARTUP(6) | // 1,953 ms + OSCCTRL_XOSCCTRL_RUNSTDBY | + OSCCTRL_XOSCCTRL_ENALC | + OSCCTRL_XOSCCTRL_IMULT(4) | + OSCCTRL_XOSCCTRL_IPTAT(3) | + OSCCTRL_XOSCCTRL_XTALEN | + OSCCTRL_XOSCCTRL_ENABLE; + while(0 == OSCCTRL->STATUS.bit.XOSCRDY1); + + OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(3) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC1_Val); /* pre-scaler = 8, input = XOSC1 */ + OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(39); /* multiply by 40 -> 80 MHz */ + OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; + while(0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL0 to be ready */ + + OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(7) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC1_Val); /* pre-scaler = 16, input = XOSC1 */ + OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(47); /* multiply by 48 -> 48 MHz */ + OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; + while(0 == OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL1 to be ready */ +#else // HWREV >= 1 + /* configure XOSC0 for a 16MHz crystal connected to XIN0/XOUT0 */ + OSCCTRL->XOSCCTRL[0].reg = + OSCCTRL_XOSCCTRL_STARTUP(6) | // 1,953 ms + OSCCTRL_XOSCCTRL_RUNSTDBY | + OSCCTRL_XOSCCTRL_ENALC | + OSCCTRL_XOSCCTRL_IMULT(4) | + OSCCTRL_XOSCCTRL_IPTAT(3) | + OSCCTRL_XOSCCTRL_XTALEN | + OSCCTRL_XOSCCTRL_ENABLE; + while (0 == OSCCTRL->STATUS.bit.XOSCRDY0); + + OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(3) | OSCCTRL_DPLLCTRLB_REFCLK( + OSCCTRL_DPLLCTRLB_REFCLK_XOSC0_Val); /* pre-scaler = 8, input = XOSC1 */ + OSCCTRL->Dpll[0].DPLLRATIO.reg = + OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(39); /* multiply by 40 -> 80 MHz */ + OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; + while (0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL0 to be ready */ + + OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(7) | OSCCTRL_DPLLCTRLB_REFCLK( + OSCCTRL_DPLLCTRLB_REFCLK_XOSC0_Val); /* pre-scaler = 16, input = XOSC1 */ + OSCCTRL->Dpll[1].DPLLRATIO.reg = + OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(47); /* multiply by 48 -> 48 MHz */ + OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; + while (0 == OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL1 to be ready */ +#endif // HWREV + + /* configure clock-generator 0 to use DPLL0 as source -> GCLK0 is used for the core */ + GCLK->GENCTRL[0].reg = + GCLK_GENCTRL_DIV(0) | + GCLK_GENCTRL_RUNSTDBY | + GCLK_GENCTRL_GENEN | + GCLK_GENCTRL_SRC_DPLL0 | /* DPLL0 */ + GCLK_GENCTRL_IDC; + while (1 == GCLK->SYNCBUSY.bit.GENCTRL0); /* wait for the synchronization between clock domains to be complete */ + + /* configure clock-generator 1 to use DPLL1 as source -> for use with some peripheral */ + GCLK->GENCTRL[1].reg = + GCLK_GENCTRL_DIV(0) | + GCLK_GENCTRL_RUNSTDBY | + GCLK_GENCTRL_GENEN | + GCLK_GENCTRL_SRC_DPLL1 | + GCLK_GENCTRL_IDC; + while (1 == GCLK->SYNCBUSY.bit.GENCTRL1); /* wait for the synchronization between clock domains to be complete */ + + /* configure clock-generator 2 to use DPLL0 as source -> for use with SERCOM */ + GCLK->GENCTRL[2].reg = + GCLK_GENCTRL_DIV(1) | /* 80MHz */ + GCLK_GENCTRL_RUNSTDBY | + GCLK_GENCTRL_GENEN | + GCLK_GENCTRL_SRC_DPLL0 | + GCLK_GENCTRL_IDC; + while (1 == GCLK->SYNCBUSY.bit.GENCTRL2); /* wait for the synchronization between clock domains to be complete */ +} + +static inline void uart_init(void) { +#if HWREV < 3 + /* configure SERCOM5 on PB02 */ + PORT->Group[1].WRCONFIG.reg = + PORT_WRCONFIG_WRPINCFG | + PORT_WRCONFIG_WRPMUX | + PORT_WRCONFIG_PMUX(3) | /* function D */ + PORT_WRCONFIG_DRVSTR | + PORT_WRCONFIG_PINMASK(0x0004) | /* PB02 */ + PORT_WRCONFIG_PMUXEN; + + MCLK->APBDMASK.bit.SERCOM5_ = 1; + GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg = + GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; /* setup SERCOM to use GLCK2 -> 80MHz */ + + SERCOM5->USART.CTRLA.reg = 0x00; /* disable SERCOM -> enable config */ + while (SERCOM5->USART.SYNCBUSY.bit.ENABLE); + + SERCOM5->USART.CTRLA.reg = /* CMODE = 0 -> async, SAMPA = 0, FORM = 0 -> USART frame, SMPR = 0 -> arithmetic baud rate */ + SERCOM_USART_CTRLA_SAMPR(1) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ + // SERCOM_USART_CTRLA_FORM(0) | /* 0 = USART Frame, 2 = LIN Master */ + SERCOM_USART_CTRLA_DORD | /* LSB first */ + SERCOM_USART_CTRLA_MODE(1) | /* 0 = Asynchronous, 1 = USART with internal clock */ + SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ + SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ + + SERCOM5->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ + SERCOM_USART_CTRLB_TXEN; /* transmitter enabled */ + SERCOM5->USART.CTRLC.reg = 0x00; + // 21.701388889 @ baud rate of 230400 bit/s, table 33-2, p 918 of DS60001507E + SERCOM5->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(7) | SERCOM_USART_BAUD_FRAC_BAUD(21); + +// SERCOM5->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC; + SERCOM5->SPI.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ + while (SERCOM5->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ +#else + /* configure SERCOM0 on PA08 */ + PORT->Group[0].WRCONFIG.reg = + PORT_WRCONFIG_WRPINCFG | + PORT_WRCONFIG_WRPMUX | + PORT_WRCONFIG_PMUX(2) | /* function C */ + PORT_WRCONFIG_DRVSTR | + PORT_WRCONFIG_PINMASK(0x0100) | /* PA08 */ + PORT_WRCONFIG_PMUXEN; + + MCLK->APBAMASK.bit.SERCOM0_ = 1; + GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; /* setup SERCOM to use GLCK2 -> 80MHz */ + + SERCOM0->USART.CTRLA.reg = 0x00; /* disable SERCOM -> enable config */ + while(SERCOM0->USART.SYNCBUSY.bit.ENABLE); + + SERCOM0->USART.CTRLA.reg = /* CMODE = 0 -> async, SAMPA = 0, FORM = 0 -> USART frame, SMPR = 0 -> arithmetic baud rate */ + SERCOM_USART_CTRLA_SAMPR(1) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ + // SERCOM_USART_CTRLA_FORM(0) | /* 0 = USART Frame, 2 = LIN Master */ + SERCOM_USART_CTRLA_DORD | /* LSB first */ + SERCOM_USART_CTRLA_MODE(1) | /* 0 = Asynchronous, 1 = USART with internal clock */ + SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ + SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ + + SERCOM0->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ + SERCOM_USART_CTRLB_TXEN; /* transmitter enabled */ + SERCOM0->USART.CTRLC.reg = 0x00; + // 21.701388889 @ baud rate of 230400 bit/s, table 33-2, p 918 of DS60001507E + SERCOM0->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(7) | SERCOM_USART_BAUD_FRAC_BAUD(21); + + // SERCOM0->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC; + SERCOM0->SPI.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ + while(SERCOM0->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ +#endif +} +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd51/boards/d5035_01/board.mk b/hw/bsp/samd51/boards/d5035_01/board.mk new file mode 100644 index 000000000..4aa6b89fe --- /dev/null +++ b/hw/bsp/samd51/boards/d5035_01/board.mk @@ -0,0 +1,21 @@ +SAM_FAMILY = same51 + +HWREV ?= 1 + +CFLAGS += \ + -D__SAME51J19A__ \ + -DCONF_CPU_FREQUENCY=80000000 \ + -DCONF_GCLK_USB_FREQUENCY=48000000 \ + -DD5035_01=1 \ + -DBOARD_NAME="\"D5035-01\"" \ + -DSVC_Handler=SVCall_Handler \ + -DHWREV=$(HWREV) + +# All source paths should be relative to the top level. +LD_FILE = $(BOARD_PATH)/same51j19a_flash.ld + +# For flash-jlink target +JLINK_DEVICE = ATSAME51J19 + +# flash using jlink +flash: flash-jlink diff --git a/hw/bsp/samd51/boards/d5035_01/same51j19a_flash.ld b/hw/bsp/samd51/boards/d5035_01/same51j19a_flash.ld new file mode 100644 index 000000000..59afb604b --- /dev/null +++ b/hw/bsp/samd51/boards/d5035_01/same51j19a_flash.ld @@ -0,0 +1,166 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAME51J19A + * + * Copyright (c) 2019 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 + bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 + qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000; + +ENTRY(Reset_Handler) + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + .bkupram (NOLOAD): + { + . = ALIGN(8); + _sbkupram = .; + *(.bkupram .bkupram.*); + . = ALIGN(8); + _ebkupram = .; + } > bkupram + + .qspi (NOLOAD): + { + . = ALIGN(8); + _sqspi = .; + *(.qspi .qspi.*); + . = ALIGN(8); + _eqspi = .; + } > qspi + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; + end = .; +} diff --git a/hw/bsp/samd51/boards/feather_m4_express/board.cmake b/hw/bsp/samd51/boards/feather_m4_express/board.cmake index d83211d9e..86d12ca24 100644 --- a/hw/bsp/samd51/boards/feather_m4_express/board.cmake +++ b/hw/bsp/samd51/boards/feather_m4_express/board.cmake @@ -1,3 +1,5 @@ +set(SAM_FAMILY samd51) + set(JLINK_DEVICE ATSAMD51J19) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) diff --git a/hw/bsp/samd51/boards/feather_m4_express/board.mk b/hw/bsp/samd51/boards/feather_m4_express/board.mk index a8a98a987..811c5f4e3 100644 --- a/hw/bsp/samd51/boards/feather_m4_express/board.mk +++ b/hw/bsp/samd51/boards/feather_m4_express/board.mk @@ -1,3 +1,5 @@ +SAM_FAMILY = samd51 + CFLAGS += -D__SAMD51J19A__ LD_FILE = $(BOARD_PATH)/$(BOARD).ld diff --git a/hw/bsp/samd51/boards/itsybitsy_m4/board.cmake b/hw/bsp/samd51/boards/itsybitsy_m4/board.cmake index d83211d9e..86d12ca24 100644 --- a/hw/bsp/samd51/boards/itsybitsy_m4/board.cmake +++ b/hw/bsp/samd51/boards/itsybitsy_m4/board.cmake @@ -1,3 +1,5 @@ +set(SAM_FAMILY samd51) + set(JLINK_DEVICE ATSAMD51J19) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) diff --git a/hw/bsp/samd51/boards/itsybitsy_m4/board.mk b/hw/bsp/samd51/boards/itsybitsy_m4/board.mk index 57a680e91..eba7070c1 100644 --- a/hw/bsp/samd51/boards/itsybitsy_m4/board.mk +++ b/hw/bsp/samd51/boards/itsybitsy_m4/board.mk @@ -1,3 +1,5 @@ +SAM_FAMILY = samd51 + CFLAGS += -D__SAMD51J19A__ # All source paths should be relative to the top level. diff --git a/hw/bsp/samd51/boards/metro_m4_express/board.cmake b/hw/bsp/samd51/boards/metro_m4_express/board.cmake index d83211d9e..86d12ca24 100644 --- a/hw/bsp/samd51/boards/metro_m4_express/board.cmake +++ b/hw/bsp/samd51/boards/metro_m4_express/board.cmake @@ -1,3 +1,5 @@ +set(SAM_FAMILY samd51) + set(JLINK_DEVICE ATSAMD51J19) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) diff --git a/hw/bsp/samd51/boards/metro_m4_express/board.mk b/hw/bsp/samd51/boards/metro_m4_express/board.mk index 57a680e91..eba7070c1 100644 --- a/hw/bsp/samd51/boards/metro_m4_express/board.mk +++ b/hw/bsp/samd51/boards/metro_m4_express/board.mk @@ -1,3 +1,5 @@ +SAM_FAMILY = samd51 + CFLAGS += -D__SAMD51J19A__ # All source paths should be relative to the top level. diff --git a/hw/bsp/samd51/boards/pybadge/board.cmake b/hw/bsp/samd51/boards/pybadge/board.cmake index d83211d9e..86d12ca24 100644 --- a/hw/bsp/samd51/boards/pybadge/board.cmake +++ b/hw/bsp/samd51/boards/pybadge/board.cmake @@ -1,3 +1,5 @@ +set(SAM_FAMILY samd51) + set(JLINK_DEVICE ATSAMD51J19) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) diff --git a/hw/bsp/samd51/boards/pybadge/board.mk b/hw/bsp/samd51/boards/pybadge/board.mk index a8a98a987..811c5f4e3 100644 --- a/hw/bsp/samd51/boards/pybadge/board.mk +++ b/hw/bsp/samd51/boards/pybadge/board.mk @@ -1,3 +1,5 @@ +SAM_FAMILY = samd51 + CFLAGS += -D__SAMD51J19A__ LD_FILE = $(BOARD_PATH)/$(BOARD).ld diff --git a/hw/bsp/samd51/boards/pyportal/board.cmake b/hw/bsp/samd51/boards/pyportal/board.cmake index d83211d9e..86d12ca24 100644 --- a/hw/bsp/samd51/boards/pyportal/board.cmake +++ b/hw/bsp/samd51/boards/pyportal/board.cmake @@ -1,3 +1,5 @@ +set(SAM_FAMILY samd51) + set(JLINK_DEVICE ATSAMD51J19) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) diff --git a/hw/bsp/samd51/boards/pyportal/board.mk b/hw/bsp/samd51/boards/pyportal/board.mk index a8a98a987..811c5f4e3 100644 --- a/hw/bsp/samd51/boards/pyportal/board.mk +++ b/hw/bsp/samd51/boards/pyportal/board.mk @@ -1,3 +1,5 @@ +SAM_FAMILY = samd51 + CFLAGS += -D__SAMD51J19A__ LD_FILE = $(BOARD_PATH)/$(BOARD).ld diff --git a/hw/bsp/samd51/boards/same54_xplained/board.cmake b/hw/bsp/samd51/boards/same54_xplained/board.cmake new file mode 100644 index 000000000..4d98205bc --- /dev/null +++ b/hw/bsp/samd51/boards/same54_xplained/board.cmake @@ -0,0 +1,10 @@ +set(SAM_FAMILY same54) + +set(JLINK_DEVICE ATSAME54P20) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/same54p20a_flash.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAME54P20A__ + ) +endfunction() diff --git a/hw/bsp/samd51/boards/same54_xplained/board.h b/hw/bsp/samd51/boards/same54_xplained/board.h new file mode 100644 index 000000000..faaa52b8e --- /dev/null +++ b/hw/bsp/samd51/boards/same54_xplained/board.h @@ -0,0 +1,50 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PIN PIN_PC18 +#define LED_STATE_ON 1 + +// Button: D5 +#define BUTTON_PIN PIN_PB31 +#define BUTTON_STATE_ACTIVE 0 + +// UART: SERCOM2 +//#define UART_TX_PIN 23 +//#define UART_RX_PIN 22 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd51/boards/same54_xplained/board.mk b/hw/bsp/samd51/boards/same54_xplained/board.mk new file mode 100644 index 000000000..d10e9e34c --- /dev/null +++ b/hw/bsp/samd51/boards/same54_xplained/board.mk @@ -0,0 +1,9 @@ +SAM_FAMILY = same54 + +CFLAGS += -D__SAME54P20A__ + +# All source paths should be relative to the top level. +LD_FILE = $(BOARD_PATH)/same54p20a_flash.ld + +# For flash-jlink target +JLINK_DEVICE = ATSAME54P20 diff --git a/hw/bsp/samd51/boards/same54_xplained/same54p20a_flash.ld b/hw/bsp/samd51/boards/same54_xplained/same54p20a_flash.ld new file mode 100644 index 000000000..8a9fd7d9f --- /dev/null +++ b/hw/bsp/samd51/boards/same54_xplained/same54p20a_flash.ld @@ -0,0 +1,166 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAME54P20A + * + * Copyright (c) 2019 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000 + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 + bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 + qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x10000; + +ENTRY(Reset_Handler) + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + .bkupram (NOLOAD): + { + . = ALIGN(8); + _sbkupram = .; + *(.bkupram .bkupram.*); + . = ALIGN(8); + _ebkupram = .; + } > bkupram + + .qspi (NOLOAD): + { + . = ALIGN(8); + _sqspi = .; + *(.qspi .qspi.*); + . = ALIGN(8); + _eqspi = .; + } > qspi + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; + end = .; +} diff --git a/hw/bsp/samd51/boards/same54_xplained/same54p20a_sram.ld b/hw/bsp/samd51/boards/same54_xplained/same54p20a_sram.ld new file mode 100644 index 000000000..c88617729 --- /dev/null +++ b/hw/bsp/samd51/boards/same54_xplained/same54p20a_sram.ld @@ -0,0 +1,165 @@ +/** + * \file + * + * \brief Linker script for running in internal SRAM on the SAME54P20A + * + * Copyright (c) 2019 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 + bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 + qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x10000; + +ENTRY(Reset_Handler) + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > ram + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > ram + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + .bkupram (NOLOAD): + { + . = ALIGN(8); + _sbkupram = .; + *(.bkupram .bkupram.*); + . = ALIGN(8); + _ebkupram = .; + } > bkupram + + .qspi (NOLOAD): + { + . = ALIGN(8); + _sqspi = .; + *(.qspi .qspi.*); + . = ALIGN(8); + _eqspi = .; + } > qspi + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; + end = .; +} diff --git a/hw/bsp/samd51/family.c b/hw/bsp/samd51/family.c index d56d9f695..abaee353b 100644 --- a/hw/bsp/samd51/family.c +++ b/hw/bsp/samd51/family.c @@ -34,8 +34,8 @@ #pragma GCC diagnostic ignored "-Wcast-qual" #endif -#include "hal/include/hal_gpio.h" -#include "hal/include/hal_init.h" +#include "hal_gpio.h" +#include "hal_init.h" #include "hpl/gclk/hpl_gclk_base.h" #include "hpl_mclk_config.h" @@ -106,9 +106,11 @@ void board_init(void) { gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); gpio_set_pin_level(LED_PIN, 0); +#ifdef BUTTON_PIN // Button init gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP); +#endif #if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) @@ -154,7 +156,11 @@ void board_led_write(bool state) { uint32_t board_button_read(void) { // button is active low + #ifdef BUTTON_PIN return gpio_get_pin_level(BUTTON_PIN) ? 0 : 1; + #else + return 0; + #endif } size_t board_get_unique_id(uint8_t id[], size_t max_len) { @@ -194,6 +200,53 @@ uint32_t board_millis(void) { return system_ticks; } +#if 0 +/* Initialize SERCOM2 for 115200 bps 8N1 using a 48 MHz clock */ +static inline void uart_init(void) { + gpio_set_pin_function(PIN_PB24, PINMUX_PB24D_SERCOM2_PAD1); + gpio_set_pin_function(PIN_PB25, PINMUX_PB25D_SERCOM2_PAD0); + + MCLK->APBBMASK.bit.SERCOM2_ = 1; + GCLK->PCHCTRL[SERCOM2_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN; + + BOARD_SERCOM->USART.CTRLA.bit.SWRST = 1; /* reset and disable SERCOM -> enable configuration */ + while (BOARD_SERCOM->USART.SYNCBUSY.bit.SWRST); + + BOARD_SERCOM->USART.CTRLA.reg = + SERCOM_USART_CTRLA_SAMPR(0) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ + SERCOM_USART_CTRLA_SAMPA(0) | /* 16x over sampling */ + SERCOM_USART_CTRLA_FORM(0) | /* 0x0 USART frame, 0x1 USART frame with parity, ... */ + SERCOM_USART_CTRLA_DORD | /* LSB first */ + SERCOM_USART_CTRLA_MODE(1) | /* 0x0 USART with external clock, 0x1 USART with internal clock */ + SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ + SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ + + BOARD_SERCOM->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ + SERCOM_USART_CTRLB_TXEN | /* transmitter enabled */ + SERCOM_USART_CTRLB_RXEN; /* receiver enabled */ + // BOARD_SERCOM->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(0) | SERCOM_USART_BAUD_FRAC_BAUD(26); /* 48000000/(16*115200) = 26.041666667 */ + BOARD_SERCOM->USART.BAUD.reg = SERCOM_USART_BAUD_BAUD(63019); /* 65536*(1−16*115200/48000000) */ + + BOARD_SERCOM->USART.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ + while (BOARD_SERCOM->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ +} + +static inline void uart_send_buffer(uint8_t const* text, size_t len) { + for (size_t i = 0; i < len; ++i) { + BOARD_SERCOM->USART.DATA.reg = text[i]; + while ((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); + } +} + +static inline void uart_send_str(const char* text) { + while (*text) { + BOARD_SERCOM->USART.DATA.reg = *text++; + while ((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); + } +} + +#endif + #endif //--------------------------------------------------------------------+ diff --git a/hw/bsp/samd51/family.cmake b/hw/bsp/samd51/family.cmake index 3ddd2e290..6d64a5fe4 100644 --- a/hw/bsp/samd51/family.cmake +++ b/hw/bsp/samd51/family.cmake @@ -1,16 +1,15 @@ include_guard() -set(SDK_DIR ${TOP}/hw/mcu/microchip/samd51) -set(CMSIS_5 ${TOP}/lib/CMSIS_5) - -# include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) +set(SDK_DIR ${TOP}/hw/mcu/microchip/${SAM_FAMILY}) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + # toolchain set up set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) -set(FAMILY_MCUS SAMD51 CACHE INTERNAL "") +set(FAMILY_MCUS SAMD51 SAME54 CACHE INTERNAL "") set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -c \"set CHIPNAME samd51\" -f target/atsame5x.cfg") #------------------------------------ @@ -27,22 +26,20 @@ function(add_board_target BOARD_TARGET) message(FATAL_ERROR "LD_FILE_${CMAKE_C_COMPILER_ID} not defined") endif () - if (NOT DEFINED STARTUP_FILE_GNU) - set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_samd51.c) - endif () + set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_${SAM_FAMILY}.c) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/gcc/system_samd51.c + ${SDK_DIR}/gcc/system_${SAM_FAMILY}.c + ${SDK_DIR}/hal/src/hal_atomic.c ${SDK_DIR}/hpl/gclk/hpl_gclk.c ${SDK_DIR}/hpl/mclk/hpl_mclk.c ${SDK_DIR}/hpl/osc32kctrl/hpl_osc32kctrl.c ${SDK_DIR}/hpl/oscctrl/hpl_oscctrl.c - ${SDK_DIR}/hal/src/hal_atomic.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${BOARD_TARGET} PUBLIC - ${SDK_DIR}/ + ${SDK_DIR} ${SDK_DIR}/config ${SDK_DIR}/include ${SDK_DIR}/hal/include diff --git a/hw/bsp/samd51/family.mk b/hw/bsp/samd51/family.mk index 7b90efad0..9b1a23db4 100644 --- a/hw/bsp/samd51/family.mk +++ b/hw/bsp/samd51/family.mk @@ -1,9 +1,10 @@ UF2_FAMILY_ID = 0x55114460 -DEPS_SUBMODULES += hw/mcu/microchip include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 +SDK_DIR = hw/mcu/microchip/${SAM_FAMILY} + CFLAGS += \ -flto \ -DCFG_TUSB_MCU=OPT_MCU_SAMD51 @@ -17,23 +18,23 @@ LDFLAGS_GCC += \ SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ - hw/mcu/microchip/samd51/gcc/gcc/startup_samd51.c \ - hw/mcu/microchip/samd51/gcc/system_samd51.c \ - hw/mcu/microchip/samd51/hpl/gclk/hpl_gclk.c \ - hw/mcu/microchip/samd51/hpl/mclk/hpl_mclk.c \ - hw/mcu/microchip/samd51/hpl/osc32kctrl/hpl_osc32kctrl.c \ - hw/mcu/microchip/samd51/hpl/oscctrl/hpl_oscctrl.c \ - hw/mcu/microchip/samd51/hal/src/hal_atomic.c + ${SDK_DIR}/gcc/gcc/startup_${SAM_FAMILY}.c \ + ${SDK_DIR}/gcc/system_${SAM_FAMILY}.c \ + ${SDK_DIR}/hpl/gclk/hpl_gclk.c \ + ${SDK_DIR}/hpl/mclk/hpl_mclk.c \ + ${SDK_DIR}/hpl/osc32kctrl/hpl_osc32kctrl.c \ + ${SDK_DIR}/hpl/oscctrl/hpl_oscctrl.c \ + ${SDK_DIR}/hal/src/hal_atomic.c INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/hw/mcu/microchip/samd51/ \ - $(TOP)/hw/mcu/microchip/samd51/config \ - $(TOP)/hw/mcu/microchip/samd51/include \ - $(TOP)/hw/mcu/microchip/samd51/hal/include \ - $(TOP)/hw/mcu/microchip/samd51/hal/utils/include \ - $(TOP)/hw/mcu/microchip/samd51/hpl/port \ - $(TOP)/hw/mcu/microchip/samd51/hri \ + $(TOP)/${SDK_DIR} \ + $(TOP)/${SDK_DIR}/config \ + $(TOP)/${SDK_DIR}/include \ + $(TOP)/${SDK_DIR}/hal/include \ + $(TOP)/${SDK_DIR}/hal/utils/include \ + $(TOP)/${SDK_DIR}/hpl/port \ + $(TOP)/${SDK_DIR}/hri \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ # flash using bossac at least version 1.8 @@ -44,3 +45,7 @@ BOSSAC = bossac flash-bossac: $(BUILD)/$(PROJECT).bin @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) $(BOSSAC) --port=$(SERIAL) -U -i --offset=0x4000 -e -w $^ -R + +# flash using edbg from https://github.com/ataradov/edbg +flash-edbg: $(BUILD)/$(PROJECT).bin + edbg --verbose -t $(MCU) -pv -f $< diff --git a/hw/bsp/same5x/boards/d5035_01/board.mk b/hw/bsp/same5x/boards/d5035_01/board.mk deleted file mode 100644 index c53411bb8..000000000 --- a/hw/bsp/same5x/boards/d5035_01/board.mk +++ /dev/null @@ -1,21 +0,0 @@ -MCU = same51 - -HWREV ?= 1 - -CFLAGS += \ - -D__SAME51J19A__ \ - -DCONF_CPU_FREQUENCY=80000000 \ - -DCONF_GCLK_USB_FREQUENCY=48000000 \ - -DD5035_01=1 \ - -DBOARD_NAME="\"D5035-01\"" \ - -DSVC_Handler=SVCall_Handler \ - -DHWREV=$(HWREV) - -# All source paths should be relative to the top level. -LD_FILE = $(BOARD_PATH)/same51j19a_flash.ld - -# For flash-jlink target -JLINK_DEVICE = ATSAME51J19 - -# flash using jlink -flash: flash-jlink diff --git a/hw/bsp/same5x/boards/d5035_01/d5035_01.c b/hw/bsp/same5x/boards/d5035_01/d5035_01.c deleted file mode 100644 index eb5768d0d..000000000 --- a/hw/bsp/same5x/boards/d5035_01/d5035_01.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Jean Gressmann - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -#include -#include "bsp/board_api.h" - -#include - -#if CONF_CPU_FREQUENCY != 80000000 -# error "CONF_CPU_FREQUENCY" must 80000000 -#endif - -#if CONF_GCLK_USB_FREQUENCY != 48000000 -# error "CONF_GCLK_USB_FREQUENCY" must 48000000 -#endif - -#if !defined(HWREV) -# error Define "HWREV" -#endif - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB_0_Handler (void) -{ - tud_int_handler(0); -} - -void USB_1_Handler (void) -{ - tud_int_handler(0); -} - -void USB_2_Handler (void) -{ - tud_int_handler(0); -} - -void USB_3_Handler (void) -{ - tud_int_handler(0); -} - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ -#define LED_PIN PIN_PA02 - -#if HWREV < 3 -# define BOARD_SERCOM SERCOM5 -#else -# define BOARD_SERCOM SERCOM0 -#endif - -static inline void init_clock(void) -{ - /* AUTOWS is enabled by default in REG_NVMCTRL_CTRLA - no need to change the number of wait states when changing the core clock */ -#if HWREV == 1 - /* configure XOSC1 for a 16MHz crystal connected to XIN1/XOUT1 */ - OSCCTRL->XOSCCTRL[1].reg = - OSCCTRL_XOSCCTRL_STARTUP(6) | // 1,953 ms - OSCCTRL_XOSCCTRL_RUNSTDBY | - OSCCTRL_XOSCCTRL_ENALC | - OSCCTRL_XOSCCTRL_IMULT(4) | - OSCCTRL_XOSCCTRL_IPTAT(3) | - OSCCTRL_XOSCCTRL_XTALEN | - OSCCTRL_XOSCCTRL_ENABLE; - while(0 == OSCCTRL->STATUS.bit.XOSCRDY1); - - OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(3) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC1_Val); /* pre-scaler = 8, input = XOSC1 */ - OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(39); /* multiply by 40 -> 80 MHz */ - OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; - while(0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL0 to be ready */ - - OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(7) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC1_Val); /* pre-scaler = 16, input = XOSC1 */ - OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(47); /* multiply by 48 -> 48 MHz */ - OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; - while(0 == OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL1 to be ready */ -#else // HWREV >= 1 - /* configure XOSC0 for a 16MHz crystal connected to XIN0/XOUT0 */ - OSCCTRL->XOSCCTRL[0].reg = - OSCCTRL_XOSCCTRL_STARTUP(6) | // 1,953 ms - OSCCTRL_XOSCCTRL_RUNSTDBY | - OSCCTRL_XOSCCTRL_ENALC | - OSCCTRL_XOSCCTRL_IMULT(4) | - OSCCTRL_XOSCCTRL_IPTAT(3) | - OSCCTRL_XOSCCTRL_XTALEN | - OSCCTRL_XOSCCTRL_ENABLE; - while(0 == OSCCTRL->STATUS.bit.XOSCRDY0); - - OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(3) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC0_Val); /* pre-scaler = 8, input = XOSC1 */ - OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(39); /* multiply by 40 -> 80 MHz */ - OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; - while(0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL0 to be ready */ - - OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(7) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC0_Val); /* pre-scaler = 16, input = XOSC1 */ - OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(47); /* multiply by 48 -> 48 MHz */ - OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; - while(0 == OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL1 to be ready */ -#endif // HWREV - - /* configure clock-generator 0 to use DPLL0 as source -> GCLK0 is used for the core */ - GCLK->GENCTRL[0].reg = - GCLK_GENCTRL_DIV(0) | - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_DPLL0 | /* DPLL0 */ - GCLK_GENCTRL_IDC ; - while(1 == GCLK->SYNCBUSY.bit.GENCTRL0); /* wait for the synchronization between clock domains to be complete */ - - /* configure clock-generator 1 to use DPLL1 as source -> for use with some peripheral */ - GCLK->GENCTRL[1].reg = - GCLK_GENCTRL_DIV(0) | - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_DPLL1 | - GCLK_GENCTRL_IDC ; - while(1 == GCLK->SYNCBUSY.bit.GENCTRL1); /* wait for the synchronization between clock domains to be complete */ - - /* configure clock-generator 2 to use DPLL0 as source -> for use with SERCOM */ - GCLK->GENCTRL[2].reg = - GCLK_GENCTRL_DIV(1) | /* 80MHz */ - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_DPLL0 | - GCLK_GENCTRL_IDC ; - while(1 == GCLK->SYNCBUSY.bit.GENCTRL2); /* wait for the synchronization between clock domains to be complete */ -} - -static inline void uart_init(void) -{ -#if HWREV < 3 - /* configure SERCOM5 on PB02 */ - PORT->Group[1].WRCONFIG.reg = - PORT_WRCONFIG_WRPINCFG | - PORT_WRCONFIG_WRPMUX | - PORT_WRCONFIG_PMUX(3) | /* function D */ - PORT_WRCONFIG_DRVSTR | - PORT_WRCONFIG_PINMASK(0x0004) | /* PB02 */ - PORT_WRCONFIG_PMUXEN; - - MCLK->APBDMASK.bit.SERCOM5_ = 1; - GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; /* setup SERCOM to use GLCK2 -> 80MHz */ - - SERCOM5->USART.CTRLA.reg = 0x00; /* disable SERCOM -> enable config */ - while(SERCOM5->USART.SYNCBUSY.bit.ENABLE); - - SERCOM5->USART.CTRLA.reg = /* CMODE = 0 -> async, SAMPA = 0, FORM = 0 -> USART frame, SMPR = 0 -> arithmetic baud rate */ - SERCOM_USART_CTRLA_SAMPR(1) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ -// SERCOM_USART_CTRLA_FORM(0) | /* 0 = USART Frame, 2 = LIN Master */ - SERCOM_USART_CTRLA_DORD | /* LSB first */ - SERCOM_USART_CTRLA_MODE(1) | /* 0 = Asynchronous, 1 = USART with internal clock */ - SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ - SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ - - SERCOM5->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ - SERCOM_USART_CTRLB_TXEN; /* transmitter enabled */ - SERCOM5->USART.CTRLC.reg = 0x00; - // 21.701388889 @ baud rate of 230400 bit/s, table 33-2, p 918 of DS60001507E - SERCOM5->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(7) | SERCOM_USART_BAUD_FRAC_BAUD(21); - -// SERCOM5->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC; - SERCOM5->SPI.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ - while(SERCOM5->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ -#else -/* configure SERCOM0 on PA08 */ - PORT->Group[0].WRCONFIG.reg = - PORT_WRCONFIG_WRPINCFG | - PORT_WRCONFIG_WRPMUX | - PORT_WRCONFIG_PMUX(2) | /* function C */ - PORT_WRCONFIG_DRVSTR | - PORT_WRCONFIG_PINMASK(0x0100) | /* PA08 */ - PORT_WRCONFIG_PMUXEN; - - MCLK->APBAMASK.bit.SERCOM0_ = 1; - GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; /* setup SERCOM to use GLCK2 -> 80MHz */ - - SERCOM0->USART.CTRLA.reg = 0x00; /* disable SERCOM -> enable config */ - while(SERCOM0->USART.SYNCBUSY.bit.ENABLE); - - SERCOM0->USART.CTRLA.reg = /* CMODE = 0 -> async, SAMPA = 0, FORM = 0 -> USART frame, SMPR = 0 -> arithmetic baud rate */ - SERCOM_USART_CTRLA_SAMPR(1) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ -// SERCOM_USART_CTRLA_FORM(0) | /* 0 = USART Frame, 2 = LIN Master */ - SERCOM_USART_CTRLA_DORD | /* LSB first */ - SERCOM_USART_CTRLA_MODE(1) | /* 0 = Asynchronous, 1 = USART with internal clock */ - SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ - SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ - - SERCOM0->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ - SERCOM_USART_CTRLB_TXEN; /* transmitter enabled */ - SERCOM0->USART.CTRLC.reg = 0x00; - // 21.701388889 @ baud rate of 230400 bit/s, table 33-2, p 918 of DS60001507E - SERCOM0->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(7) | SERCOM_USART_BAUD_FRAC_BAUD(21); - -// SERCOM0->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC; - SERCOM0->SPI.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ - while(SERCOM0->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ -#endif -} - -static inline void uart_send_buffer(uint8_t const *text, size_t len) -{ - for (size_t i = 0; i < len; ++i) { - BOARD_SERCOM->USART.DATA.reg = text[i]; - while((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_SPI_INTFLAG_TXC) == 0); - } -} - -static inline void uart_send_str(const char* text) -{ - while (*text) { - BOARD_SERCOM->USART.DATA.reg = *text++; - while((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_SPI_INTFLAG_TXC) == 0); - } -} - - -void board_init(void) -{ - init_clock(); - - SystemCoreClock = CONF_CPU_FREQUENCY; - -#if CFG_TUSB_OS == OPT_OS_NONE - SysTick_Config(CONF_CPU_FREQUENCY / 1000); -#endif - - uart_init(); -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " UART initialized\n"); - tu_printf(BOARD_NAME " reset cause %#02x\n", RSTC->RCAUSE.reg); -#endif - - // Led init - gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); - gpio_set_pin_level(LED_PIN, 0); - -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " LED pin configured\n"); -#endif - -#if CFG_TUSB_OS == OPT_OS_FREERTOS - // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB_0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_3_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); -#endif - - -#if CFG_TUD_ENABLED -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " USB device enabled\n"); -#endif - - /* USB clock init - * The USB module requires a GCLK_USB of 48 MHz ~ 0.25% clock - * for low speed and full speed operation. */ - hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN); - hri_mclk_set_AHBMASK_USB_bit(MCLK); - hri_mclk_set_APBBMASK_USB_bit(MCLK); - - // USB pin init - gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT); - gpio_set_pin_level(PIN_PA24, false); - gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF); - gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT); - gpio_set_pin_level(PIN_PA25, false); - gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF); - - gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM); - gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP); - - -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " USB device configured\n"); -#endif -#endif -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) -{ - gpio_set_pin_level(LED_PIN, state); -} - -uint32_t board_button_read(void) -{ - // this board has no button - return 0; -} - -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; - return 0; -} - -int board_uart_write(void const * buf, int len) -{ - if (len < 0) { - uart_send_str(buf); - } else { - uart_send_buffer(buf, len); - } - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; - -void SysTick_Handler(void) -{ - system_ticks++; -} - -uint32_t board_millis(void) -{ - return system_ticks; -} -#endif - -// Required by __libc_init_array in startup code if we are compiling using -// -nostdlib/-nostartfiles. -void _init(void) -{ - -} diff --git a/hw/bsp/same5x/boards/d5035_01/same51j19a_flash.ld b/hw/bsp/same5x/boards/d5035_01/same51j19a_flash.ld deleted file mode 100644 index 486043f22..000000000 --- a/hw/bsp/same5x/boards/d5035_01/same51j19a_flash.ld +++ /dev/null @@ -1,164 +0,0 @@ -/** - * \file - * - * \brief Linker script for running in internal FLASH on the SAME51J19A - * - * Copyright (c) 2019 Microchip Technology Inc. - * - * \asf_license_start - * - * \page License - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the Licence at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * \asf_license_stop - * - */ - - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -SEARCH_DIR(.) - -/* Memory Spaces Definitions */ -MEMORY -{ - rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 - bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 - qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 -} - -/* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000; - -/* Section Definitions */ -SECTIONS -{ - .text : - { - . = ALIGN(4); - _sfixed = .; - KEEP(*(.vectors .vectors.*)) - *(.text .text.* .gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) - *(.rodata .rodata* .gnu.linkonce.r.*) - *(.ARM.extab* .gnu.linkonce.armextab.*) - - /* Support C constructors, and C destructors in both user code - and the C library. This also provides support for C++ code. */ - . = ALIGN(4); - KEEP(*(.init)) - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - - . = ALIGN(4); - _efixed = .; /* End of text section */ - } > rom - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - PROVIDE_HIDDEN (__exidx_start = .); - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > rom - PROVIDE_HIDDEN (__exidx_end = .); - - . = ALIGN(4); - _etext = .; - - .relocate : AT (_etext) - { - . = ALIGN(4); - _srelocate = .; - *(.ramfunc .ramfunc.*); - *(.data .data.*); - . = ALIGN(4); - _erelocate = .; - } > ram - - .bkupram (NOLOAD): - { - . = ALIGN(8); - _sbkupram = .; - *(.bkupram .bkupram.*); - . = ALIGN(8); - _ebkupram = .; - } > bkupram - - .qspi (NOLOAD): - { - . = ALIGN(8); - _sqspi = .; - *(.qspi .qspi.*); - . = ALIGN(8); - _eqspi = .; - } > qspi - - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = . ; - _szero = .; - *(.bss .bss.*) - *(COMMON) - . = ALIGN(4); - _ebss = . ; - _ezero = .; - } > ram - - /* stack section */ - .stack (NOLOAD): - { - . = ALIGN(8); - _sstack = .; - . = . + STACK_SIZE; - . = ALIGN(8); - _estack = .; - } > ram - - . = ALIGN(4); - _end = . ; - end = .; -} diff --git a/hw/bsp/same5x/boards/same54_xplained/board.mk b/hw/bsp/same5x/boards/same54_xplained/board.mk deleted file mode 100644 index 41cf95bfc..000000000 --- a/hw/bsp/same5x/boards/same54_xplained/board.mk +++ /dev/null @@ -1,12 +0,0 @@ -MCU = same54 - -CFLAGS += \ - -DCONF_CPU_FREQUENCY=48000000 \ - -D__SAME54P20A__ \ - -DBOARD_NAME="\"Microchip SAM E54 Xplained Pro\"" - -# All source paths should be relative to the top level. -LD_FILE = $(BOARD_PATH)/same54p20a_flash.ld - -# For flash-jlink target -JLINK_DEVICE = ATSAME54P20 diff --git a/hw/bsp/same5x/boards/same54_xplained/same54_xplained.c b/hw/bsp/same5x/boards/same54_xplained/same54_xplained.c deleted file mode 100644 index 93adea63e..000000000 --- a/hw/bsp/same5x/boards/same54_xplained/same54_xplained.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2021 Jean Gressmann - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -#include -#include "bsp/board_api.h" - -#include - - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB_0_Handler(void) -{ - tud_int_handler(0); -} - -void USB_1_Handler(void) -{ - tud_int_handler(0); -} - -void USB_2_Handler(void) -{ - tud_int_handler(0); -} - -void USB_3_Handler(void) -{ - tud_int_handler(0); -} - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ -#define LED_PIN PIN_PC18 -#define BUTTON_PIN PIN_PB31 -#define BOARD_SERCOM SERCOM2 - -/** Initializes the clocks from the external 12 MHz crystal - * - * The goal of this setup is to preserve the second PLL - * for the application code while still having a reasonable - * 48 MHz clock for USB / UART. - * - * GCLK0: CONF_CPU_FREQUENCY (default 120 MHz) from PLL0 - * GCLK1: unused - * GCLK2: 12 MHz from XOSC1 - * DFLL48M: closed loop from GLCK2 - * GCLK3: 48 MHz - */ -static inline void init_clock_xtal(void) -{ - /* configure for a 12MHz crystal connected to XIN1/XOUT1 */ - OSCCTRL->XOSCCTRL[1].reg = - OSCCTRL_XOSCCTRL_STARTUP(6) | // 1.953 ms - OSCCTRL_XOSCCTRL_RUNSTDBY | - OSCCTRL_XOSCCTRL_ENALC | - OSCCTRL_XOSCCTRL_IMULT(4) | OSCCTRL_XOSCCTRL_IPTAT(3) | // 8MHz to 16MHz - OSCCTRL_XOSCCTRL_XTALEN | - OSCCTRL_XOSCCTRL_ENABLE; - while(0 == OSCCTRL->STATUS.bit.XOSCRDY1); - - OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(2) | OSCCTRL_DPLLCTRLB_REFCLK_XOSC1; /* 12MHz / 6 = 2Mhz, input = XOSC1 */ - OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR((CONF_CPU_FREQUENCY / 1000000 / 2) - 1); /* multiply to get CONF_CPU_FREQUENCY (default = 120MHz) */ - OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; - while(0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL0 to be ready */ - - /* configure clock-generator 0 to use DPLL0 as source -> GCLK0 is used for the core */ - GCLK->GENCTRL[0].reg = - GCLK_GENCTRL_DIV(0) | - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_DPLL0 | - GCLK_GENCTRL_IDC; - while(1 == GCLK->SYNCBUSY.bit.GENCTRL0); /* wait for the synchronization between clock domains to be complete */ - - // configure GCLK2 for 12MHz from XOSC1 - GCLK->GENCTRL[2].reg = - GCLK_GENCTRL_DIV(0) | - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_XOSC1 | - GCLK_GENCTRL_IDC; - while(1 == GCLK->SYNCBUSY.bit.GENCTRL2); /* wait for the synchronization between clock domains to be complete */ - - /* setup DFLL48M to use GLCK2 */ - GCLK->PCHCTRL[OSCCTRL_GCLK_ID_DFLL48].reg = GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; - - OSCCTRL->DFLLCTRLA.reg = 0; - while(1 == OSCCTRL->DFLLSYNC.bit.ENABLE); - - OSCCTRL->DFLLCTRLB.reg = OSCCTRL_DFLLCTRLB_MODE | OSCCTRL_DFLLCTRLB_WAITLOCK; - OSCCTRL->DFLLMUL.bit.MUL = 4; // 4 * 12MHz -> 48MHz - - OSCCTRL->DFLLCTRLA.reg = - OSCCTRL_DFLLCTRLA_ENABLE | - OSCCTRL_DFLLCTRLA_RUNSTDBY; - while(1 == OSCCTRL->DFLLSYNC.bit.ENABLE); - - // setup 48 MHz GCLK3 from DFLL48M - GCLK->GENCTRL[3].reg = - GCLK_GENCTRL_DIV(0) | - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_DFLL | - GCLK_GENCTRL_IDC; - while(1 == GCLK->SYNCBUSY.bit.GENCTRL3); -} - -/* Initialize SERCOM2 for 115200 bps 8N1 using a 48 MHz clock */ -static inline void uart_init(void) -{ - gpio_set_pin_function(PIN_PB24, PINMUX_PB24D_SERCOM2_PAD1); - gpio_set_pin_function(PIN_PB25, PINMUX_PB25D_SERCOM2_PAD0); - - MCLK->APBBMASK.bit.SERCOM2_ = 1; - GCLK->PCHCTRL[SERCOM2_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN; - - BOARD_SERCOM->USART.CTRLA.bit.SWRST = 1; /* reset and disable SERCOM -> enable configuration */ - while (BOARD_SERCOM->USART.SYNCBUSY.bit.SWRST); - - BOARD_SERCOM->USART.CTRLA.reg = - SERCOM_USART_CTRLA_SAMPR(0) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ - SERCOM_USART_CTRLA_SAMPA(0) | /* 16x over sampling */ - SERCOM_USART_CTRLA_FORM(0) | /* 0x0 USART frame, 0x1 USART frame with parity, ... */ - SERCOM_USART_CTRLA_DORD | /* LSB first */ - SERCOM_USART_CTRLA_MODE(1) | /* 0x0 USART with external clock, 0x1 USART with internal clock */ - SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ - SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ - - BOARD_SERCOM->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ - SERCOM_USART_CTRLB_TXEN | /* transmitter enabled */ - SERCOM_USART_CTRLB_RXEN; /* receiver enabled */ - // BOARD_SERCOM->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(0) | SERCOM_USART_BAUD_FRAC_BAUD(26); /* 48000000/(16*115200) = 26.041666667 */ - BOARD_SERCOM->USART.BAUD.reg = SERCOM_USART_BAUD_BAUD(63019); /* 65536*(1−16*115200/48000000) */ - - BOARD_SERCOM->USART.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ - while (BOARD_SERCOM->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ -} - -static inline void uart_send_buffer(uint8_t const *text, size_t len) -{ - for (size_t i = 0; i < len; ++i) { - BOARD_SERCOM->USART.DATA.reg = text[i]; - while((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); - } -} - -static inline void uart_send_str(const char* text) -{ - while (*text) { - BOARD_SERCOM->USART.DATA.reg = *text++; - while((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); - } -} - - -void board_init(void) -{ - // Uncomment this line and change the GCLK for UART/USB to run off the XTAL. - // init_clock_xtal(); - - SystemCoreClock = CONF_CPU_FREQUENCY; - -#if CFG_TUSB_OS == OPT_OS_NONE - SysTick_Config(CONF_CPU_FREQUENCY / 1000); -#endif - - uart_init(); - -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " UART initialized\n"); - tu_printf(BOARD_NAME " reset cause %#02x\n", RSTC->RCAUSE.reg); -#endif - - // LED0 init - gpio_set_pin_function(LED_PIN, GPIO_PIN_FUNCTION_OFF); - gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); - board_led_write(0); - -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " LED pin configured\n"); -#endif - - // BTN0 init - gpio_set_pin_function(BUTTON_PIN, GPIO_PIN_FUNCTION_OFF); - gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); - gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP); - -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " Button pin configured\n"); -#endif - -#if CFG_TUSB_OS == OPT_OS_FREERTOS - // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB_0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_3_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); -#endif - - -#if CFG_TUD_ENABLED -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " USB device enabled\n"); -#endif - - /* USB clock init - * The USB module requires a GCLK_USB of 48 MHz ~ 0.25% clock - * for low speed and full speed operation. - */ - hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK0_Val | GCLK_PCHCTRL_CHEN); - hri_mclk_set_AHBMASK_USB_bit(MCLK); - hri_mclk_set_APBBMASK_USB_bit(MCLK); - - // USB pin init - gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT); - gpio_set_pin_level(PIN_PA24, false); - gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF); - gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT); - gpio_set_pin_level(PIN_PA25, false); - gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF); - - gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM); - gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP); - - -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " USB device configured\n"); -#endif -#endif -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) -{ - gpio_set_pin_level(LED_PIN, !state); -} - -uint32_t board_button_read(void) -{ - return (PORT->Group[1].IN.reg & 0x80000000) != 0x80000000; -} - -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; - return 0; -} - -int board_uart_write(void const * buf, int len) -{ - if (len < 0) { - uart_send_str(buf); - } else { - uart_send_buffer(buf, len); - } - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; - -void SysTick_Handler(void) -{ - system_ticks++; -} - -uint32_t board_millis(void) -{ - return system_ticks; -} -#endif - -// Required by __libc_init_array in startup code if we are compiling using -// -nostdlib/-nostartfiles. -void _init(void) -{ - -} diff --git a/hw/bsp/same5x/boards/same54_xplained/same54p20a_flash.ld b/hw/bsp/same5x/boards/same54_xplained/same54p20a_flash.ld deleted file mode 100644 index 7a7f1be46..000000000 --- a/hw/bsp/same5x/boards/same54_xplained/same54p20a_flash.ld +++ /dev/null @@ -1,163 +0,0 @@ -/** - * \file - * - * \brief Linker script for running in internal FLASH on the SAME54P20A - * - * Copyright (c) 2019 Microchip Technology Inc. - * - * \asf_license_start - * - * \page License - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the Licence at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * \asf_license_stop - * - */ - - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -SEARCH_DIR(.) - -/* Memory Spaces Definitions */ -MEMORY -{ - rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000 - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 - bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 - qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 -} - -/* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x10000; - -/* Section Definitions */ -SECTIONS -{ - .text : - { - . = ALIGN(4); - _sfixed = .; - KEEP(*(.vectors .vectors.*)) - *(.text .text.* .gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) - *(.rodata .rodata* .gnu.linkonce.r.*) - *(.ARM.extab* .gnu.linkonce.armextab.*) - - /* Support C constructors, and C destructors in both user code - and the C library. This also provides support for C++ code. */ - . = ALIGN(4); - KEEP(*(.init)) - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - - . = ALIGN(4); - _efixed = .; /* End of text section */ - } > rom - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - PROVIDE_HIDDEN (__exidx_start = .); - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > rom - PROVIDE_HIDDEN (__exidx_end = .); - - . = ALIGN(4); - _etext = .; - - .relocate : AT (_etext) - { - . = ALIGN(4); - _srelocate = .; - *(.ramfunc .ramfunc.*); - *(.data .data.*); - . = ALIGN(4); - _erelocate = .; - } > ram - - .bkupram (NOLOAD): - { - . = ALIGN(8); - _sbkupram = .; - *(.bkupram .bkupram.*); - . = ALIGN(8); - _ebkupram = .; - } > bkupram - - .qspi (NOLOAD): - { - . = ALIGN(8); - _sqspi = .; - *(.qspi .qspi.*); - . = ALIGN(8); - _eqspi = .; - } > qspi - - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = . ; - _szero = .; - *(.bss .bss.*) - *(COMMON) - . = ALIGN(4); - _ebss = . ; - _ezero = .; - } > ram - - /* stack section */ - .stack (NOLOAD): - { - . = ALIGN(8); - _sstack = .; - . = . + STACK_SIZE; - . = ALIGN(8); - _estack = .; - } > ram - - . = ALIGN(4); - _end = . ; -} diff --git a/hw/bsp/same5x/boards/same54_xplained/same54p20a_sram.ld b/hw/bsp/same5x/boards/same54_xplained/same54p20a_sram.ld deleted file mode 100644 index c768f9c9a..000000000 --- a/hw/bsp/same5x/boards/same54_xplained/same54p20a_sram.ld +++ /dev/null @@ -1,162 +0,0 @@ -/** - * \file - * - * \brief Linker script for running in internal SRAM on the SAME54P20A - * - * Copyright (c) 2019 Microchip Technology Inc. - * - * \asf_license_start - * - * \page License - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the Licence at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * \asf_license_stop - * - */ - - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -SEARCH_DIR(.) - -/* Memory Spaces Definitions */ -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 - bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 - qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 -} - -/* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x10000; - -/* Section Definitions */ -SECTIONS -{ - .text : - { - . = ALIGN(4); - _sfixed = .; - KEEP(*(.vectors .vectors.*)) - *(.text .text.* .gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) - *(.rodata .rodata* .gnu.linkonce.r.*) - *(.ARM.extab* .gnu.linkonce.armextab.*) - - /* Support C constructors, and C destructors in both user code - and the C library. This also provides support for C++ code. */ - . = ALIGN(4); - KEEP(*(.init)) - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - - . = ALIGN(4); - _efixed = .; /* End of text section */ - } > ram - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - PROVIDE_HIDDEN (__exidx_start = .); - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > ram - PROVIDE_HIDDEN (__exidx_end = .); - - . = ALIGN(4); - _etext = .; - - .relocate : AT (_etext) - { - . = ALIGN(4); - _srelocate = .; - *(.ramfunc .ramfunc.*); - *(.data .data.*); - . = ALIGN(4); - _erelocate = .; - } > ram - - .bkupram (NOLOAD): - { - . = ALIGN(8); - _sbkupram = .; - *(.bkupram .bkupram.*); - . = ALIGN(8); - _ebkupram = .; - } > bkupram - - .qspi (NOLOAD): - { - . = ALIGN(8); - _sqspi = .; - *(.qspi .qspi.*); - . = ALIGN(8); - _eqspi = .; - } > qspi - - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = . ; - _szero = .; - *(.bss .bss.*) - *(COMMON) - . = ALIGN(4); - _ebss = . ; - _ezero = .; - } > ram - - /* stack section */ - .stack (NOLOAD): - { - . = ALIGN(8); - _sstack = .; - . = . + STACK_SIZE; - . = ALIGN(8); - _estack = .; - } > ram - - . = ALIGN(4); - _end = . ; -} diff --git a/hw/bsp/same5x/family.mk b/hw/bsp/same5x/family.mk deleted file mode 100644 index b2bf0d359..000000000 --- a/hw/bsp/same5x/family.mk +++ /dev/null @@ -1,38 +0,0 @@ -DEPS_SUBMODULES += hw/mcu/microchip - -SDK_DIR = hw/mcu/microchip/$(MCU) -include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= cortex-m4 - -CFLAGS += \ - -mthumb \ - -mlong-calls \ - -nostdlib -nostartfiles \ - -DCFG_TUSB_MCU=OPT_MCU_SAME5X - -# SAM driver is flooded with -Wcast-qual which slow down complication significantly -CFLAGS_SKIP += -Wcast-qual - -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs - -SRC_C += \ - src/portable/microchip/samd/dcd_samd.c \ - $(SDK_DIR)/gcc/gcc/startup_$(MCU).c \ - $(SDK_DIR)/gcc/system_$(MCU).c \ - $(SDK_DIR)/hal/utils/src/utils_syscalls.c - -INC += \ - $(TOP)/$(SDK_DIR) \ - $(TOP)/$(SDK_DIR)/config \ - $(TOP)/$(SDK_DIR)/include \ - $(TOP)/$(SDK_DIR)/hal/include \ - $(TOP)/$(SDK_DIR)/hal/utils/include \ - $(TOP)/$(SDK_DIR)/hpl/port \ - $(TOP)/$(SDK_DIR)/hri \ - $(TOP)/$(SDK_DIR)/CMSIS/Include - -# flash using edbg from https://github.com/ataradov/edbg -flash-edbg: $(BUILD)/$(PROJECT).bin - edbg --verbose -t $(MCU) -pv -f $< - -flash: flash-edbg diff --git a/hw/bsp/saml2x/boards/atsaml21_xpro/board.cmake b/hw/bsp/saml2x/boards/atsaml21_xpro/board.cmake index 6312ff89d..874b741cc 100644 --- a/hw/bsp/saml2x/boards/atsaml21_xpro/board.cmake +++ b/hw/bsp/saml2x/boards/atsaml21_xpro/board.cmake @@ -1,4 +1,4 @@ -set(MCU_VARIANT saml21) +set(SAM_FAMILY saml21) set(JLINK_DEVICE ATSAML21J18) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/saml21j18b_flash.ld) diff --git a/hw/bsp/saml2x/boards/atsaml21_xpro/board.mk b/hw/bsp/saml2x/boards/atsaml21_xpro/board.mk index 75179fc58..4ebfa7e71 100644 --- a/hw/bsp/saml2x/boards/atsaml21_xpro/board.mk +++ b/hw/bsp/saml2x/boards/atsaml21_xpro/board.mk @@ -1,4 +1,4 @@ -MCU_VARIANT = saml21 +SAM_FAMILY = saml21 CFLAGS += -D__SAML21J18B__ diff --git a/hw/bsp/saml2x/boards/saml22_feather/board.cmake b/hw/bsp/saml2x/boards/saml22_feather/board.cmake index 7db751e45..7fd79d2ce 100644 --- a/hw/bsp/saml2x/boards/saml22_feather/board.cmake +++ b/hw/bsp/saml2x/boards/saml22_feather/board.cmake @@ -1,4 +1,4 @@ -set(MCU_VARIANT saml22) +set(SAM_FAMILY saml22) set(JLINK_DEVICE ATSAML22J18) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) diff --git a/hw/bsp/saml2x/boards/saml22_feather/board.mk b/hw/bsp/saml2x/boards/saml22_feather/board.mk index 76d86de25..c7817ff70 100644 --- a/hw/bsp/saml2x/boards/saml22_feather/board.mk +++ b/hw/bsp/saml2x/boards/saml22_feather/board.mk @@ -1,4 +1,4 @@ -MCU_VARIANT = saml22 +SAM_FAMILY = saml22 CFLAGS += -D__SAML22J18A__ diff --git a/hw/bsp/saml2x/boards/sensorwatch_m0/board.cmake b/hw/bsp/saml2x/boards/sensorwatch_m0/board.cmake index 162ef127b..67d26475f 100644 --- a/hw/bsp/saml2x/boards/sensorwatch_m0/board.cmake +++ b/hw/bsp/saml2x/boards/sensorwatch_m0/board.cmake @@ -1,4 +1,4 @@ -set(MCU_VARIANT saml22) +set(SAM_FAMILY saml22) set(JLINK_DEVICE ATSAML21J18) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) diff --git a/hw/bsp/saml2x/boards/sensorwatch_m0/board.mk b/hw/bsp/saml2x/boards/sensorwatch_m0/board.mk index 76d86de25..c7817ff70 100644 --- a/hw/bsp/saml2x/boards/sensorwatch_m0/board.mk +++ b/hw/bsp/saml2x/boards/sensorwatch_m0/board.mk @@ -1,4 +1,4 @@ -MCU_VARIANT = saml22 +SAM_FAMILY = saml22 CFLAGS += -D__SAML22J18A__ diff --git a/hw/bsp/saml2x/family.cmake b/hw/bsp/saml2x/family.cmake index d8a62aef3..8390cdc9c 100644 --- a/hw/bsp/saml2x/family.cmake +++ b/hw/bsp/saml2x/family.cmake @@ -3,7 +3,7 @@ include_guard() # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) -set(SDK_DIR ${TOP}/hw/mcu/microchip/${MCU_VARIANT}) +set(SDK_DIR ${TOP}/hw/mcu/microchip/${SAM_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # toolchain set up @@ -27,11 +27,11 @@ function(add_board_target BOARD_TARGET) message(FATAL_ERROR "LD_FILE_${CMAKE_C_COMPILER_ID} not defined") endif () - set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_${MCU_VARIANT}.c) + set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_${SAM_FAMILY}.c) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/gcc/system_${MCU_VARIANT}.c + ${SDK_DIR}/gcc/system_${SAM_FAMILY}.c ${SDK_DIR}/hal/src/hal_atomic.c ${SDK_DIR}/hpl/gclk/hpl_gclk.c ${SDK_DIR}/hpl/mclk/hpl_mclk.c diff --git a/hw/bsp/saml2x/family.mk b/hw/bsp/saml2x/family.mk index e01d7522e..65dfe5032 100644 --- a/hw/bsp/saml2x/family.mk +++ b/hw/bsp/saml2x/family.mk @@ -1,5 +1,5 @@ UF2_FAMILY_ID = 0x68ed2b88 -SDK_DIR = hw/mcu/microchip/$(MCU_VARIANT) +SDK_DIR = hw/mcu/microchip/$(SAM_FAMILY) include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus @@ -22,8 +22,8 @@ LDFLAGS_GCC += \ SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ - $(SDK_DIR)/gcc/gcc/startup_$(MCU_VARIANT).c \ - $(SDK_DIR)/gcc/system_$(MCU_VARIANT).c \ + $(SDK_DIR)/gcc/gcc/startup_$(SAM_FAMILY).c \ + $(SDK_DIR)/gcc/system_$(SAM_FAMILY).c \ $(SDK_DIR)/hal/src/hal_atomic.c \ $(SDK_DIR)/hpl/gclk/hpl_gclk.c \ $(SDK_DIR)/hpl/mclk/hpl_mclk.c \ -- cgit v1.3.1 From 59f8e9dff942baf7f0b05ef4927672ee2627f54b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 15:17:07 +0700 Subject: rename to samd5x_e5x --- .idea/cmake.xml | 40 +- .idea/runConfigurations/rp2040.xml | 2 +- hw/bsp/samd51/FreeRTOSConfig/FreeRTOSConfig.h | 149 ------- hw/bsp/samd51/boards/d5035_01/board.cmake | 13 - hw/bsp/samd51/boards/d5035_01/board.h | 198 --------- hw/bsp/samd51/boards/d5035_01/board.mk | 21 - hw/bsp/samd51/boards/d5035_01/same51j19a_flash.ld | 166 -------- .../samd51/boards/feather_m4_express/board.cmake | 10 - hw/bsp/samd51/boards/feather_m4_express/board.h | 67 --- hw/bsp/samd51/boards/feather_m4_express/board.mk | 10 - .../feather_m4_express/feather_m4_express.ld | 166 -------- hw/bsp/samd51/boards/itsybitsy_m4/board.cmake | 10 - hw/bsp/samd51/boards/itsybitsy_m4/board.h | 50 --- hw/bsp/samd51/boards/itsybitsy_m4/board.mk | 11 - hw/bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld | 166 -------- hw/bsp/samd51/boards/metro_m4_express/board.cmake | 10 - hw/bsp/samd51/boards/metro_m4_express/board.h | 66 --- hw/bsp/samd51/boards/metro_m4_express/board.mk | 11 - .../boards/metro_m4_express/metro_m4_express.ld | 166 -------- hw/bsp/samd51/boards/pybadge/board.cmake | 10 - hw/bsp/samd51/boards/pybadge/board.h | 50 --- hw/bsp/samd51/boards/pybadge/board.mk | 10 - hw/bsp/samd51/boards/pybadge/pybadge.ld | 166 -------- hw/bsp/samd51/boards/pyportal/board.cmake | 10 - hw/bsp/samd51/boards/pyportal/board.h | 50 --- hw/bsp/samd51/boards/pyportal/board.mk | 10 - hw/bsp/samd51/boards/pyportal/pyportal.ld | 166 -------- hw/bsp/samd51/boards/same54_xplained/board.cmake | 10 - hw/bsp/samd51/boards/same54_xplained/board.h | 50 --- hw/bsp/samd51/boards/same54_xplained/board.mk | 9 - .../boards/same54_xplained/same54p20a_flash.ld | 166 -------- .../boards/same54_xplained/same54p20a_sram.ld | 165 -------- hw/bsp/samd51/family.c | 448 --------------------- hw/bsp/samd51/family.cmake | 109 ----- hw/bsp/samd51/family.mk | 51 --- hw/bsp/samd5x_e5x/FreeRTOSConfig/FreeRTOSConfig.h | 149 +++++++ hw/bsp/samd5x_e5x/boards/d5035_01/board.cmake | 13 + hw/bsp/samd5x_e5x/boards/d5035_01/board.h | 198 +++++++++ hw/bsp/samd5x_e5x/boards/d5035_01/board.mk | 21 + .../samd5x_e5x/boards/d5035_01/same51j19a_flash.ld | 166 ++++++++ .../boards/feather_m4_express/board.cmake | 10 + .../samd5x_e5x/boards/feather_m4_express/board.h | 67 +++ .../samd5x_e5x/boards/feather_m4_express/board.mk | 10 + .../feather_m4_express/feather_m4_express.ld | 166 ++++++++ hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.cmake | 10 + hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.h | 50 +++ hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.mk | 11 + .../samd5x_e5x/boards/itsybitsy_m4/itsybitsy_m4.ld | 166 ++++++++ .../samd5x_e5x/boards/metro_m4_express/board.cmake | 10 + hw/bsp/samd5x_e5x/boards/metro_m4_express/board.h | 66 +++ hw/bsp/samd5x_e5x/boards/metro_m4_express/board.mk | 11 + .../boards/metro_m4_express/metro_m4_express.ld | 166 ++++++++ hw/bsp/samd5x_e5x/boards/pybadge/board.cmake | 10 + hw/bsp/samd5x_e5x/boards/pybadge/board.h | 50 +++ hw/bsp/samd5x_e5x/boards/pybadge/board.mk | 10 + hw/bsp/samd5x_e5x/boards/pybadge/pybadge.ld | 166 ++++++++ hw/bsp/samd5x_e5x/boards/pyportal/board.cmake | 10 + hw/bsp/samd5x_e5x/boards/pyportal/board.h | 50 +++ hw/bsp/samd5x_e5x/boards/pyportal/board.mk | 10 + hw/bsp/samd5x_e5x/boards/pyportal/pyportal.ld | 166 ++++++++ .../samd5x_e5x/boards/same54_xplained/board.cmake | 10 + hw/bsp/samd5x_e5x/boards/same54_xplained/board.h | 50 +++ hw/bsp/samd5x_e5x/boards/same54_xplained/board.mk | 9 + .../boards/same54_xplained/same54p20a_flash.ld | 166 ++++++++ .../boards/same54_xplained/same54p20a_sram.ld | 165 ++++++++ hw/bsp/samd5x_e5x/family.c | 448 +++++++++++++++++++++ hw/bsp/samd5x_e5x/family.cmake | 109 +++++ hw/bsp/samd5x_e5x/family.mk | 51 +++ 68 files changed, 2808 insertions(+), 2774 deletions(-) delete mode 100644 hw/bsp/samd51/FreeRTOSConfig/FreeRTOSConfig.h delete mode 100644 hw/bsp/samd51/boards/d5035_01/board.cmake delete mode 100644 hw/bsp/samd51/boards/d5035_01/board.h delete mode 100644 hw/bsp/samd51/boards/d5035_01/board.mk delete mode 100644 hw/bsp/samd51/boards/d5035_01/same51j19a_flash.ld delete mode 100644 hw/bsp/samd51/boards/feather_m4_express/board.cmake delete mode 100644 hw/bsp/samd51/boards/feather_m4_express/board.h delete mode 100644 hw/bsp/samd51/boards/feather_m4_express/board.mk delete mode 100644 hw/bsp/samd51/boards/feather_m4_express/feather_m4_express.ld delete mode 100644 hw/bsp/samd51/boards/itsybitsy_m4/board.cmake delete mode 100644 hw/bsp/samd51/boards/itsybitsy_m4/board.h delete mode 100644 hw/bsp/samd51/boards/itsybitsy_m4/board.mk delete mode 100644 hw/bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld delete mode 100644 hw/bsp/samd51/boards/metro_m4_express/board.cmake delete mode 100644 hw/bsp/samd51/boards/metro_m4_express/board.h delete mode 100644 hw/bsp/samd51/boards/metro_m4_express/board.mk delete mode 100644 hw/bsp/samd51/boards/metro_m4_express/metro_m4_express.ld delete mode 100644 hw/bsp/samd51/boards/pybadge/board.cmake delete mode 100644 hw/bsp/samd51/boards/pybadge/board.h delete mode 100644 hw/bsp/samd51/boards/pybadge/board.mk delete mode 100644 hw/bsp/samd51/boards/pybadge/pybadge.ld delete mode 100644 hw/bsp/samd51/boards/pyportal/board.cmake delete mode 100644 hw/bsp/samd51/boards/pyportal/board.h delete mode 100644 hw/bsp/samd51/boards/pyportal/board.mk delete mode 100644 hw/bsp/samd51/boards/pyportal/pyportal.ld delete mode 100644 hw/bsp/samd51/boards/same54_xplained/board.cmake delete mode 100644 hw/bsp/samd51/boards/same54_xplained/board.h delete mode 100644 hw/bsp/samd51/boards/same54_xplained/board.mk delete mode 100644 hw/bsp/samd51/boards/same54_xplained/same54p20a_flash.ld delete mode 100644 hw/bsp/samd51/boards/same54_xplained/same54p20a_sram.ld delete mode 100644 hw/bsp/samd51/family.c delete mode 100644 hw/bsp/samd51/family.cmake delete mode 100644 hw/bsp/samd51/family.mk create mode 100644 hw/bsp/samd5x_e5x/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/samd5x_e5x/boards/d5035_01/board.cmake create mode 100644 hw/bsp/samd5x_e5x/boards/d5035_01/board.h create mode 100644 hw/bsp/samd5x_e5x/boards/d5035_01/board.mk create mode 100644 hw/bsp/samd5x_e5x/boards/d5035_01/same51j19a_flash.ld create mode 100644 hw/bsp/samd5x_e5x/boards/feather_m4_express/board.cmake create mode 100644 hw/bsp/samd5x_e5x/boards/feather_m4_express/board.h create mode 100644 hw/bsp/samd5x_e5x/boards/feather_m4_express/board.mk create mode 100644 hw/bsp/samd5x_e5x/boards/feather_m4_express/feather_m4_express.ld create mode 100644 hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.cmake create mode 100644 hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.h create mode 100644 hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.mk create mode 100644 hw/bsp/samd5x_e5x/boards/itsybitsy_m4/itsybitsy_m4.ld create mode 100644 hw/bsp/samd5x_e5x/boards/metro_m4_express/board.cmake create mode 100644 hw/bsp/samd5x_e5x/boards/metro_m4_express/board.h create mode 100644 hw/bsp/samd5x_e5x/boards/metro_m4_express/board.mk create mode 100644 hw/bsp/samd5x_e5x/boards/metro_m4_express/metro_m4_express.ld create mode 100644 hw/bsp/samd5x_e5x/boards/pybadge/board.cmake create mode 100644 hw/bsp/samd5x_e5x/boards/pybadge/board.h create mode 100644 hw/bsp/samd5x_e5x/boards/pybadge/board.mk create mode 100644 hw/bsp/samd5x_e5x/boards/pybadge/pybadge.ld create mode 100644 hw/bsp/samd5x_e5x/boards/pyportal/board.cmake create mode 100644 hw/bsp/samd5x_e5x/boards/pyportal/board.h create mode 100644 hw/bsp/samd5x_e5x/boards/pyportal/board.mk create mode 100644 hw/bsp/samd5x_e5x/boards/pyportal/pyportal.ld create mode 100644 hw/bsp/samd5x_e5x/boards/same54_xplained/board.cmake create mode 100644 hw/bsp/samd5x_e5x/boards/same54_xplained/board.h create mode 100644 hw/bsp/samd5x_e5x/boards/same54_xplained/board.mk create mode 100644 hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_flash.ld create mode 100644 hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_sram.ld create mode 100644 hw/bsp/samd5x_e5x/family.c create mode 100644 hw/bsp/samd5x_e5x/family.cmake create mode 100644 hw/bsp/samd5x_e5x/family.mk diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 22199b103..56c85f21d 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -41,10 +41,32 @@ + + + + + + + + + + + + + + + + + + + + + - - - + + + + @@ -89,6 +111,18 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/rp2040.xml b/.idea/runConfigurations/rp2040.xml index 51ab7b5cc..da5a8f1ee 100644 --- a/.idea/runConfigurations/rp2040.xml +++ b/.idea/runConfigurations/rp2040.xml @@ -1,5 +1,5 @@ - + diff --git a/hw/bsp/samd51/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/samd51/FreeRTOSConfig/FreeRTOSConfig.h deleted file mode 100644 index a283560fe..000000000 --- a/hw/bsp/samd51/FreeRTOSConfig/FreeRTOSConfig.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * FreeRTOS Kernel V10.0.0 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. If you wish to use our Amazon - * FreeRTOS name, please do so in a fair use way that does not cause confusion. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ - - -#ifndef FREERTOS_CONFIG_H -#define FREERTOS_CONFIG_H - -/*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * - * See http://www.freertos.org/a00110.html. - *----------------------------------------------------------*/ - -// skip if included from IAR assembler -#ifndef __IASMARM__ - #include "sam.h" -#endif - -/* Cortex M23/M33 port configuration. */ -#define configENABLE_MPU 0 -#define configENABLE_FPU 1 -#define configENABLE_TRUSTZONE 0 -#define configMINIMAL_SECURE_STACK_SIZE (1024) - -#define configUSE_PREEMPTION 1 -#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 -#define configCPU_CLOCK_HZ SystemCoreClock -#define configTICK_RATE_HZ ( 1000 ) -#define configMAX_PRIORITIES ( 5 ) -#define configMINIMAL_STACK_SIZE ( 128 ) -#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*6*1024 ) -#define configMAX_TASK_NAME_LEN 16 -#define configUSE_16_BIT_TICKS 0 -#define configIDLE_SHOULD_YIELD 1 -#define configUSE_MUTEXES 1 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configUSE_COUNTING_SEMAPHORES 1 -#define configQUEUE_REGISTRY_SIZE 4 -#define configUSE_QUEUE_SETS 0 -#define configUSE_TIME_SLICING 0 -#define configUSE_NEWLIB_REENTRANT 0 -#define configENABLE_BACKWARD_COMPATIBILITY 1 -#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 - -#define configSUPPORT_STATIC_ALLOCATION 1 -#define configSUPPORT_DYNAMIC_ALLOCATION 0 - -/* Hook function related definitions. */ -#define configUSE_IDLE_HOOK 0 -#define configUSE_TICK_HOOK 0 -#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning -#define configCHECK_FOR_STACK_OVERFLOW 2 -#define configCHECK_HANDLER_INSTALLATION 0 - -/* Run time and task stats gathering related definitions. */ -#define configGENERATE_RUN_TIME_STATS 0 -#define configRECORD_STACK_HIGH_ADDRESS 1 -#define configUSE_TRACE_FACILITY 1 // legacy trace -#define configUSE_STATS_FORMATTING_FUNCTIONS 0 - -/* Co-routine definitions. */ -#define configUSE_CO_ROUTINES 0 -#define configMAX_CO_ROUTINE_PRIORITIES 2 - -/* Software timer related definitions. */ -#define configUSE_TIMERS 1 -#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) -#define configTIMER_QUEUE_LENGTH 32 -#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE - -/* Optional functions - most linkers will remove unused functions anyway. */ -#define INCLUDE_vTaskPrioritySet 0 -#define INCLUDE_uxTaskPriorityGet 0 -#define INCLUDE_vTaskDelete 0 -#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY -#define INCLUDE_xResumeFromISR 0 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 -#define INCLUDE_xTaskGetSchedulerState 0 -#define INCLUDE_xTaskGetCurrentTaskHandle 1 -#define INCLUDE_uxTaskGetStackHighWaterMark 0 -#define INCLUDE_xTaskGetIdleTaskHandle 0 -#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 -#define INCLUDE_pcTaskGetTaskName 0 -#define INCLUDE_eTaskGetState 0 -#define INCLUDE_xEventGroupSetBitFromISR 0 -#define INCLUDE_xTimerPendFunctionCall 0 - -/* FreeRTOS hooks to NVIC vectors */ -#define xPortPendSVHandler PendSV_Handler -#define xPortSysTickHandler SysTick_Handler -#define vPortSVCHandler SVC_Handler - -//--------------------------------------------------------------------+ -// Interrupt nesting behavior configuration. -//--------------------------------------------------------------------+ - -// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header -#define configPRIO_BITS 3 - -/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ -#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<XOSCCTRL[1].reg = - OSCCTRL_XOSCCTRL_STARTUP(6) | // 1,953 ms - OSCCTRL_XOSCCTRL_RUNSTDBY | - OSCCTRL_XOSCCTRL_ENALC | - OSCCTRL_XOSCCTRL_IMULT(4) | - OSCCTRL_XOSCCTRL_IPTAT(3) | - OSCCTRL_XOSCCTRL_XTALEN | - OSCCTRL_XOSCCTRL_ENABLE; - while(0 == OSCCTRL->STATUS.bit.XOSCRDY1); - - OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(3) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC1_Val); /* pre-scaler = 8, input = XOSC1 */ - OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(39); /* multiply by 40 -> 80 MHz */ - OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; - while(0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL0 to be ready */ - - OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(7) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC1_Val); /* pre-scaler = 16, input = XOSC1 */ - OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(47); /* multiply by 48 -> 48 MHz */ - OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; - while(0 == OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL1 to be ready */ -#else // HWREV >= 1 - /* configure XOSC0 for a 16MHz crystal connected to XIN0/XOUT0 */ - OSCCTRL->XOSCCTRL[0].reg = - OSCCTRL_XOSCCTRL_STARTUP(6) | // 1,953 ms - OSCCTRL_XOSCCTRL_RUNSTDBY | - OSCCTRL_XOSCCTRL_ENALC | - OSCCTRL_XOSCCTRL_IMULT(4) | - OSCCTRL_XOSCCTRL_IPTAT(3) | - OSCCTRL_XOSCCTRL_XTALEN | - OSCCTRL_XOSCCTRL_ENABLE; - while (0 == OSCCTRL->STATUS.bit.XOSCRDY0); - - OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(3) | OSCCTRL_DPLLCTRLB_REFCLK( - OSCCTRL_DPLLCTRLB_REFCLK_XOSC0_Val); /* pre-scaler = 8, input = XOSC1 */ - OSCCTRL->Dpll[0].DPLLRATIO.reg = - OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(39); /* multiply by 40 -> 80 MHz */ - OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; - while (0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL0 to be ready */ - - OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(7) | OSCCTRL_DPLLCTRLB_REFCLK( - OSCCTRL_DPLLCTRLB_REFCLK_XOSC0_Val); /* pre-scaler = 16, input = XOSC1 */ - OSCCTRL->Dpll[1].DPLLRATIO.reg = - OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(47); /* multiply by 48 -> 48 MHz */ - OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; - while (0 == OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL1 to be ready */ -#endif // HWREV - - /* configure clock-generator 0 to use DPLL0 as source -> GCLK0 is used for the core */ - GCLK->GENCTRL[0].reg = - GCLK_GENCTRL_DIV(0) | - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_DPLL0 | /* DPLL0 */ - GCLK_GENCTRL_IDC; - while (1 == GCLK->SYNCBUSY.bit.GENCTRL0); /* wait for the synchronization between clock domains to be complete */ - - /* configure clock-generator 1 to use DPLL1 as source -> for use with some peripheral */ - GCLK->GENCTRL[1].reg = - GCLK_GENCTRL_DIV(0) | - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_DPLL1 | - GCLK_GENCTRL_IDC; - while (1 == GCLK->SYNCBUSY.bit.GENCTRL1); /* wait for the synchronization between clock domains to be complete */ - - /* configure clock-generator 2 to use DPLL0 as source -> for use with SERCOM */ - GCLK->GENCTRL[2].reg = - GCLK_GENCTRL_DIV(1) | /* 80MHz */ - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_DPLL0 | - GCLK_GENCTRL_IDC; - while (1 == GCLK->SYNCBUSY.bit.GENCTRL2); /* wait for the synchronization between clock domains to be complete */ -} - -static inline void uart_init(void) { -#if HWREV < 3 - /* configure SERCOM5 on PB02 */ - PORT->Group[1].WRCONFIG.reg = - PORT_WRCONFIG_WRPINCFG | - PORT_WRCONFIG_WRPMUX | - PORT_WRCONFIG_PMUX(3) | /* function D */ - PORT_WRCONFIG_DRVSTR | - PORT_WRCONFIG_PINMASK(0x0004) | /* PB02 */ - PORT_WRCONFIG_PMUXEN; - - MCLK->APBDMASK.bit.SERCOM5_ = 1; - GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg = - GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; /* setup SERCOM to use GLCK2 -> 80MHz */ - - SERCOM5->USART.CTRLA.reg = 0x00; /* disable SERCOM -> enable config */ - while (SERCOM5->USART.SYNCBUSY.bit.ENABLE); - - SERCOM5->USART.CTRLA.reg = /* CMODE = 0 -> async, SAMPA = 0, FORM = 0 -> USART frame, SMPR = 0 -> arithmetic baud rate */ - SERCOM_USART_CTRLA_SAMPR(1) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ - // SERCOM_USART_CTRLA_FORM(0) | /* 0 = USART Frame, 2 = LIN Master */ - SERCOM_USART_CTRLA_DORD | /* LSB first */ - SERCOM_USART_CTRLA_MODE(1) | /* 0 = Asynchronous, 1 = USART with internal clock */ - SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ - SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ - - SERCOM5->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ - SERCOM_USART_CTRLB_TXEN; /* transmitter enabled */ - SERCOM5->USART.CTRLC.reg = 0x00; - // 21.701388889 @ baud rate of 230400 bit/s, table 33-2, p 918 of DS60001507E - SERCOM5->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(7) | SERCOM_USART_BAUD_FRAC_BAUD(21); - -// SERCOM5->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC; - SERCOM5->SPI.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ - while (SERCOM5->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ -#else - /* configure SERCOM0 on PA08 */ - PORT->Group[0].WRCONFIG.reg = - PORT_WRCONFIG_WRPINCFG | - PORT_WRCONFIG_WRPMUX | - PORT_WRCONFIG_PMUX(2) | /* function C */ - PORT_WRCONFIG_DRVSTR | - PORT_WRCONFIG_PINMASK(0x0100) | /* PA08 */ - PORT_WRCONFIG_PMUXEN; - - MCLK->APBAMASK.bit.SERCOM0_ = 1; - GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; /* setup SERCOM to use GLCK2 -> 80MHz */ - - SERCOM0->USART.CTRLA.reg = 0x00; /* disable SERCOM -> enable config */ - while(SERCOM0->USART.SYNCBUSY.bit.ENABLE); - - SERCOM0->USART.CTRLA.reg = /* CMODE = 0 -> async, SAMPA = 0, FORM = 0 -> USART frame, SMPR = 0 -> arithmetic baud rate */ - SERCOM_USART_CTRLA_SAMPR(1) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ - // SERCOM_USART_CTRLA_FORM(0) | /* 0 = USART Frame, 2 = LIN Master */ - SERCOM_USART_CTRLA_DORD | /* LSB first */ - SERCOM_USART_CTRLA_MODE(1) | /* 0 = Asynchronous, 1 = USART with internal clock */ - SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ - SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ - - SERCOM0->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ - SERCOM_USART_CTRLB_TXEN; /* transmitter enabled */ - SERCOM0->USART.CTRLC.reg = 0x00; - // 21.701388889 @ baud rate of 230400 bit/s, table 33-2, p 918 of DS60001507E - SERCOM0->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(7) | SERCOM_USART_BAUD_FRAC_BAUD(21); - - // SERCOM0->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC; - SERCOM0->SPI.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ - while(SERCOM0->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ -#endif -} -#endif - -#ifdef __cplusplus - } -#endif - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd51/boards/d5035_01/board.mk b/hw/bsp/samd51/boards/d5035_01/board.mk deleted file mode 100644 index 4aa6b89fe..000000000 --- a/hw/bsp/samd51/boards/d5035_01/board.mk +++ /dev/null @@ -1,21 +0,0 @@ -SAM_FAMILY = same51 - -HWREV ?= 1 - -CFLAGS += \ - -D__SAME51J19A__ \ - -DCONF_CPU_FREQUENCY=80000000 \ - -DCONF_GCLK_USB_FREQUENCY=48000000 \ - -DD5035_01=1 \ - -DBOARD_NAME="\"D5035-01\"" \ - -DSVC_Handler=SVCall_Handler \ - -DHWREV=$(HWREV) - -# All source paths should be relative to the top level. -LD_FILE = $(BOARD_PATH)/same51j19a_flash.ld - -# For flash-jlink target -JLINK_DEVICE = ATSAME51J19 - -# flash using jlink -flash: flash-jlink diff --git a/hw/bsp/samd51/boards/d5035_01/same51j19a_flash.ld b/hw/bsp/samd51/boards/d5035_01/same51j19a_flash.ld deleted file mode 100644 index 59afb604b..000000000 --- a/hw/bsp/samd51/boards/d5035_01/same51j19a_flash.ld +++ /dev/null @@ -1,166 +0,0 @@ -/** - * \file - * - * \brief Linker script for running in internal FLASH on the SAME51J19A - * - * Copyright (c) 2019 Microchip Technology Inc. - * - * \asf_license_start - * - * \page License - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the Licence at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * \asf_license_stop - * - */ - - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -SEARCH_DIR(.) - -/* Memory Spaces Definitions */ -MEMORY -{ - rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 - bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 - qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 -} - -/* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000; - -ENTRY(Reset_Handler) - -/* Section Definitions */ -SECTIONS -{ - .text : - { - . = ALIGN(4); - _sfixed = .; - KEEP(*(.vectors .vectors.*)) - *(.text .text.* .gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) - *(.rodata .rodata* .gnu.linkonce.r.*) - *(.ARM.extab* .gnu.linkonce.armextab.*) - - /* Support C constructors, and C destructors in both user code - and the C library. This also provides support for C++ code. */ - . = ALIGN(4); - KEEP(*(.init)) - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - - . = ALIGN(4); - _efixed = .; /* End of text section */ - } > rom - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - PROVIDE_HIDDEN (__exidx_start = .); - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > rom - PROVIDE_HIDDEN (__exidx_end = .); - - . = ALIGN(4); - _etext = .; - - .relocate : AT (_etext) - { - . = ALIGN(4); - _srelocate = .; - *(.ramfunc .ramfunc.*); - *(.data .data.*); - . = ALIGN(4); - _erelocate = .; - } > ram - - .bkupram (NOLOAD): - { - . = ALIGN(8); - _sbkupram = .; - *(.bkupram .bkupram.*); - . = ALIGN(8); - _ebkupram = .; - } > bkupram - - .qspi (NOLOAD): - { - . = ALIGN(8); - _sqspi = .; - *(.qspi .qspi.*); - . = ALIGN(8); - _eqspi = .; - } > qspi - - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = . ; - _szero = .; - *(.bss .bss.*) - *(COMMON) - . = ALIGN(4); - _ebss = . ; - _ezero = .; - } > ram - - /* stack section */ - .stack (NOLOAD): - { - . = ALIGN(8); - _sstack = .; - . = . + STACK_SIZE; - . = ALIGN(8); - _estack = .; - } > ram - - . = ALIGN(4); - _end = . ; - end = .; -} diff --git a/hw/bsp/samd51/boards/feather_m4_express/board.cmake b/hw/bsp/samd51/boards/feather_m4_express/board.cmake deleted file mode 100644 index 86d12ca24..000000000 --- a/hw/bsp/samd51/boards/feather_m4_express/board.cmake +++ /dev/null @@ -1,10 +0,0 @@ -set(SAM_FAMILY samd51) - -set(JLINK_DEVICE ATSAMD51J19) -set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) - -function(update_board TARGET) - target_compile_definitions(${TARGET} PUBLIC - __SAMD51J19A__ - ) -endfunction() diff --git a/hw/bsp/samd51/boards/feather_m4_express/board.h b/hw/bsp/samd51/boards/feather_m4_express/board.h deleted file mode 100644 index 83de04266..000000000 --- a/hw/bsp/samd51/boards/feather_m4_express/board.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#define _PINNUM(port, pin) ((port)*32 + (pin)) - -// LED -#define LED_PIN 23 -#define LED_STATE_ON 1 - -// Button -#define BUTTON_PIN 16 // D5 -#define BUTTON_STATE_ACTIVE 0 - -// UART -#define UART_TX_PIN (32 + 17) -#define UART_RX_PIN (32 + 16) - -// SPI for USB host shield -#define MAX3421_SERCOM_ID 1 // SERCOM2 -#define MAX3421_SERCOM_FUNCTION 2 // function C - -#define MAX3421_SCK_PIN _PINNUM(0, 17) -#define MAX3421_MOSI_PIN _PINNUM(1, 23) -#define MAX3421_MISO_PIN _PINNUM(1, 22) -#define MAX3421_TX_PAD 2 // MOSI = PAD_3, SCK = PAD_1 -#define MAX3421_RX_PAD 2 // MISO = PAD_2 - -#define MAX3421_CS_PIN 20 // D10 - -#define MAX3421_INTR_PIN 19 // D9 -#define MAX3421_INTR_EIC_ID 3 // EIC3 - -#ifdef __cplusplus - } -#endif - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd51/boards/feather_m4_express/board.mk b/hw/bsp/samd51/boards/feather_m4_express/board.mk deleted file mode 100644 index 811c5f4e3..000000000 --- a/hw/bsp/samd51/boards/feather_m4_express/board.mk +++ /dev/null @@ -1,10 +0,0 @@ -SAM_FAMILY = samd51 - -CFLAGS += -D__SAMD51J19A__ - -LD_FILE = $(BOARD_PATH)/$(BOARD).ld - -# For flash-jlink target -JLINK_DEVICE = ATSAMD51J19 - -flash: flash-bossac diff --git a/hw/bsp/samd51/boards/feather_m4_express/feather_m4_express.ld b/hw/bsp/samd51/boards/feather_m4_express/feather_m4_express.ld deleted file mode 100644 index 1408c3018..000000000 --- a/hw/bsp/samd51/boards/feather_m4_express/feather_m4_express.ld +++ /dev/null @@ -1,166 +0,0 @@ -/** - * \file - * - * \brief Linker script for running in internal FLASH on the SAMD51G19A - * - * Copyright (c) 2017 Microchip Technology Inc. - * - * \asf_license_start - * - * \page License - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the Licence at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * \asf_license_stop - * - */ - - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -SEARCH_DIR(.) - -/* Memory Spaces Definitions */ -MEMORY -{ - rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 - bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 - qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 -} - -/* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; - -ENTRY(Reset_Handler) - -/* Section Definitions */ -SECTIONS -{ - .text : - { - . = ALIGN(4); - _sfixed = .; - KEEP(*(.vectors .vectors.*)) - *(.text .text.* .gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) - *(.rodata .rodata* .gnu.linkonce.r.*) - *(.ARM.extab* .gnu.linkonce.armextab.*) - - /* Support C constructors, and C destructors in both user code - and the C library. This also provides support for C++ code. */ - . = ALIGN(4); - KEEP(*(.init)) - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - - . = ALIGN(4); - _efixed = .; /* End of text section */ - } > rom - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - PROVIDE_HIDDEN (__exidx_start = .); - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > rom - PROVIDE_HIDDEN (__exidx_end = .); - - . = ALIGN(4); - _etext = .; - - .relocate : AT (_etext) - { - . = ALIGN(4); - _srelocate = .; - *(.ramfunc .ramfunc.*); - *(.data .data.*); - . = ALIGN(4); - _erelocate = .; - } > ram - - .bkupram (NOLOAD): - { - . = ALIGN(8); - _sbkupram = .; - *(.bkupram .bkupram.*); - . = ALIGN(8); - _ebkupram = .; - } > bkupram - - .qspi (NOLOAD): - { - . = ALIGN(8); - _sqspi = .; - *(.qspi .qspi.*); - . = ALIGN(8); - _eqspi = .; - } > qspi - - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = . ; - _szero = .; - *(.bss .bss.*) - *(COMMON) - . = ALIGN(4); - _ebss = . ; - _ezero = .; - end = .; - } > ram - - /* stack section */ - .stack (NOLOAD): - { - . = ALIGN(8); - _sstack = .; - . = . + STACK_SIZE; - . = ALIGN(8); - _estack = .; - } > ram - - . = ALIGN(4); - _end = . ; -} diff --git a/hw/bsp/samd51/boards/itsybitsy_m4/board.cmake b/hw/bsp/samd51/boards/itsybitsy_m4/board.cmake deleted file mode 100644 index 86d12ca24..000000000 --- a/hw/bsp/samd51/boards/itsybitsy_m4/board.cmake +++ /dev/null @@ -1,10 +0,0 @@ -set(SAM_FAMILY samd51) - -set(JLINK_DEVICE ATSAMD51J19) -set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) - -function(update_board TARGET) - target_compile_definitions(${TARGET} PUBLIC - __SAMD51J19A__ - ) -endfunction() diff --git a/hw/bsp/samd51/boards/itsybitsy_m4/board.h b/hw/bsp/samd51/boards/itsybitsy_m4/board.h deleted file mode 100644 index 272315771..000000000 --- a/hw/bsp/samd51/boards/itsybitsy_m4/board.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -// LED -#define LED_PIN 22 -#define LED_STATE_ON 1 - -// Button -#define BUTTON_PIN 18 // D5 -#define BUTTON_STATE_ACTIVE 0 - -// UART -#define UART_TX_PIN 16 -#define UART_RX_PIN 17 - -#ifdef __cplusplus - } -#endif - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd51/boards/itsybitsy_m4/board.mk b/hw/bsp/samd51/boards/itsybitsy_m4/board.mk deleted file mode 100644 index eba7070c1..000000000 --- a/hw/bsp/samd51/boards/itsybitsy_m4/board.mk +++ /dev/null @@ -1,11 +0,0 @@ -SAM_FAMILY = samd51 - -CFLAGS += -D__SAMD51J19A__ - -# All source paths should be relative to the top level. -LD_FILE = $(BOARD_PATH)/$(BOARD).ld - -# For flash-jlink target -JLINK_DEVICE = ATSAMD51J19 - -flash: flash-bossac diff --git a/hw/bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld b/hw/bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld deleted file mode 100644 index 1408c3018..000000000 --- a/hw/bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld +++ /dev/null @@ -1,166 +0,0 @@ -/** - * \file - * - * \brief Linker script for running in internal FLASH on the SAMD51G19A - * - * Copyright (c) 2017 Microchip Technology Inc. - * - * \asf_license_start - * - * \page License - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the Licence at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * \asf_license_stop - * - */ - - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -SEARCH_DIR(.) - -/* Memory Spaces Definitions */ -MEMORY -{ - rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 - bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 - qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 -} - -/* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; - -ENTRY(Reset_Handler) - -/* Section Definitions */ -SECTIONS -{ - .text : - { - . = ALIGN(4); - _sfixed = .; - KEEP(*(.vectors .vectors.*)) - *(.text .text.* .gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) - *(.rodata .rodata* .gnu.linkonce.r.*) - *(.ARM.extab* .gnu.linkonce.armextab.*) - - /* Support C constructors, and C destructors in both user code - and the C library. This also provides support for C++ code. */ - . = ALIGN(4); - KEEP(*(.init)) - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - - . = ALIGN(4); - _efixed = .; /* End of text section */ - } > rom - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - PROVIDE_HIDDEN (__exidx_start = .); - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > rom - PROVIDE_HIDDEN (__exidx_end = .); - - . = ALIGN(4); - _etext = .; - - .relocate : AT (_etext) - { - . = ALIGN(4); - _srelocate = .; - *(.ramfunc .ramfunc.*); - *(.data .data.*); - . = ALIGN(4); - _erelocate = .; - } > ram - - .bkupram (NOLOAD): - { - . = ALIGN(8); - _sbkupram = .; - *(.bkupram .bkupram.*); - . = ALIGN(8); - _ebkupram = .; - } > bkupram - - .qspi (NOLOAD): - { - . = ALIGN(8); - _sqspi = .; - *(.qspi .qspi.*); - . = ALIGN(8); - _eqspi = .; - } > qspi - - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = . ; - _szero = .; - *(.bss .bss.*) - *(COMMON) - . = ALIGN(4); - _ebss = . ; - _ezero = .; - end = .; - } > ram - - /* stack section */ - .stack (NOLOAD): - { - . = ALIGN(8); - _sstack = .; - . = . + STACK_SIZE; - . = ALIGN(8); - _estack = .; - } > ram - - . = ALIGN(4); - _end = . ; -} diff --git a/hw/bsp/samd51/boards/metro_m4_express/board.cmake b/hw/bsp/samd51/boards/metro_m4_express/board.cmake deleted file mode 100644 index 86d12ca24..000000000 --- a/hw/bsp/samd51/boards/metro_m4_express/board.cmake +++ /dev/null @@ -1,10 +0,0 @@ -set(SAM_FAMILY samd51) - -set(JLINK_DEVICE ATSAMD51J19) -set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) - -function(update_board TARGET) - target_compile_definitions(${TARGET} PUBLIC - __SAMD51J19A__ - ) -endfunction() diff --git a/hw/bsp/samd51/boards/metro_m4_express/board.h b/hw/bsp/samd51/boards/metro_m4_express/board.h deleted file mode 100644 index b3b80db89..000000000 --- a/hw/bsp/samd51/boards/metro_m4_express/board.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -// LED -#define LED_PIN 16 -#define LED_STATE_ON 1 - -// Button: D5 -#define BUTTON_PIN (32+14) -#define BUTTON_STATE_ACTIVE 0 - -// UART -#define UART_TX_PIN 23 -#define UART_RX_PIN 22 - -// SPI for USB host shield -#define MAX3421_SERCOM_ID 2 // SERCOM2 -#define MAX3421_SERCOM_FUNCTION 2 // function C - -#define MAX3421_SCK_PIN 13 -#define MAX3421_MOSI_PIN 12 -#define MAX3421_MISO_PIN 14 -#define MAX3421_TX_PAD 0 // MOSI = PAD_0, SCK = PAD_1 -#define MAX3421_RX_PAD 2 // MISO = PAD_2 - -#define MAX3421_CS_PIN 18 // D10 - -#define MAX3421_INTR_PIN 20 // D9 -#define MAX3421_INTR_EIC_ID 4 // EIC4 - - -#ifdef __cplusplus - } -#endif - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd51/boards/metro_m4_express/board.mk b/hw/bsp/samd51/boards/metro_m4_express/board.mk deleted file mode 100644 index eba7070c1..000000000 --- a/hw/bsp/samd51/boards/metro_m4_express/board.mk +++ /dev/null @@ -1,11 +0,0 @@ -SAM_FAMILY = samd51 - -CFLAGS += -D__SAMD51J19A__ - -# All source paths should be relative to the top level. -LD_FILE = $(BOARD_PATH)/$(BOARD).ld - -# For flash-jlink target -JLINK_DEVICE = ATSAMD51J19 - -flash: flash-bossac diff --git a/hw/bsp/samd51/boards/metro_m4_express/metro_m4_express.ld b/hw/bsp/samd51/boards/metro_m4_express/metro_m4_express.ld deleted file mode 100644 index 1408c3018..000000000 --- a/hw/bsp/samd51/boards/metro_m4_express/metro_m4_express.ld +++ /dev/null @@ -1,166 +0,0 @@ -/** - * \file - * - * \brief Linker script for running in internal FLASH on the SAMD51G19A - * - * Copyright (c) 2017 Microchip Technology Inc. - * - * \asf_license_start - * - * \page License - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the Licence at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * \asf_license_stop - * - */ - - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -SEARCH_DIR(.) - -/* Memory Spaces Definitions */ -MEMORY -{ - rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 - bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 - qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 -} - -/* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; - -ENTRY(Reset_Handler) - -/* Section Definitions */ -SECTIONS -{ - .text : - { - . = ALIGN(4); - _sfixed = .; - KEEP(*(.vectors .vectors.*)) - *(.text .text.* .gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) - *(.rodata .rodata* .gnu.linkonce.r.*) - *(.ARM.extab* .gnu.linkonce.armextab.*) - - /* Support C constructors, and C destructors in both user code - and the C library. This also provides support for C++ code. */ - . = ALIGN(4); - KEEP(*(.init)) - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - - . = ALIGN(4); - _efixed = .; /* End of text section */ - } > rom - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - PROVIDE_HIDDEN (__exidx_start = .); - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > rom - PROVIDE_HIDDEN (__exidx_end = .); - - . = ALIGN(4); - _etext = .; - - .relocate : AT (_etext) - { - . = ALIGN(4); - _srelocate = .; - *(.ramfunc .ramfunc.*); - *(.data .data.*); - . = ALIGN(4); - _erelocate = .; - } > ram - - .bkupram (NOLOAD): - { - . = ALIGN(8); - _sbkupram = .; - *(.bkupram .bkupram.*); - . = ALIGN(8); - _ebkupram = .; - } > bkupram - - .qspi (NOLOAD): - { - . = ALIGN(8); - _sqspi = .; - *(.qspi .qspi.*); - . = ALIGN(8); - _eqspi = .; - } > qspi - - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = . ; - _szero = .; - *(.bss .bss.*) - *(COMMON) - . = ALIGN(4); - _ebss = . ; - _ezero = .; - end = .; - } > ram - - /* stack section */ - .stack (NOLOAD): - { - . = ALIGN(8); - _sstack = .; - . = . + STACK_SIZE; - . = ALIGN(8); - _estack = .; - } > ram - - . = ALIGN(4); - _end = . ; -} diff --git a/hw/bsp/samd51/boards/pybadge/board.cmake b/hw/bsp/samd51/boards/pybadge/board.cmake deleted file mode 100644 index 86d12ca24..000000000 --- a/hw/bsp/samd51/boards/pybadge/board.cmake +++ /dev/null @@ -1,10 +0,0 @@ -set(SAM_FAMILY samd51) - -set(JLINK_DEVICE ATSAMD51J19) -set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) - -function(update_board TARGET) - target_compile_definitions(${TARGET} PUBLIC - __SAMD51J19A__ - ) -endfunction() diff --git a/hw/bsp/samd51/boards/pybadge/board.h b/hw/bsp/samd51/boards/pybadge/board.h deleted file mode 100644 index 4629643fd..000000000 --- a/hw/bsp/samd51/boards/pybadge/board.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -// LED -#define LED_PIN 23 -#define LED_STATE_ON 1 - -// Button -#define BUTTON_PIN 16 // D5 -#define BUTTON_STATE_ACTIVE 0 - -// UART -#define UART_TX_PIN (32 + 17) -#define UART_RX_PIN (32 + 16) - -#ifdef __cplusplus - } -#endif - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd51/boards/pybadge/board.mk b/hw/bsp/samd51/boards/pybadge/board.mk deleted file mode 100644 index 811c5f4e3..000000000 --- a/hw/bsp/samd51/boards/pybadge/board.mk +++ /dev/null @@ -1,10 +0,0 @@ -SAM_FAMILY = samd51 - -CFLAGS += -D__SAMD51J19A__ - -LD_FILE = $(BOARD_PATH)/$(BOARD).ld - -# For flash-jlink target -JLINK_DEVICE = ATSAMD51J19 - -flash: flash-bossac diff --git a/hw/bsp/samd51/boards/pybadge/pybadge.ld b/hw/bsp/samd51/boards/pybadge/pybadge.ld deleted file mode 100644 index 1408c3018..000000000 --- a/hw/bsp/samd51/boards/pybadge/pybadge.ld +++ /dev/null @@ -1,166 +0,0 @@ -/** - * \file - * - * \brief Linker script for running in internal FLASH on the SAMD51G19A - * - * Copyright (c) 2017 Microchip Technology Inc. - * - * \asf_license_start - * - * \page License - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the Licence at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * \asf_license_stop - * - */ - - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -SEARCH_DIR(.) - -/* Memory Spaces Definitions */ -MEMORY -{ - rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 - bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 - qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 -} - -/* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; - -ENTRY(Reset_Handler) - -/* Section Definitions */ -SECTIONS -{ - .text : - { - . = ALIGN(4); - _sfixed = .; - KEEP(*(.vectors .vectors.*)) - *(.text .text.* .gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) - *(.rodata .rodata* .gnu.linkonce.r.*) - *(.ARM.extab* .gnu.linkonce.armextab.*) - - /* Support C constructors, and C destructors in both user code - and the C library. This also provides support for C++ code. */ - . = ALIGN(4); - KEEP(*(.init)) - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - - . = ALIGN(4); - _efixed = .; /* End of text section */ - } > rom - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - PROVIDE_HIDDEN (__exidx_start = .); - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > rom - PROVIDE_HIDDEN (__exidx_end = .); - - . = ALIGN(4); - _etext = .; - - .relocate : AT (_etext) - { - . = ALIGN(4); - _srelocate = .; - *(.ramfunc .ramfunc.*); - *(.data .data.*); - . = ALIGN(4); - _erelocate = .; - } > ram - - .bkupram (NOLOAD): - { - . = ALIGN(8); - _sbkupram = .; - *(.bkupram .bkupram.*); - . = ALIGN(8); - _ebkupram = .; - } > bkupram - - .qspi (NOLOAD): - { - . = ALIGN(8); - _sqspi = .; - *(.qspi .qspi.*); - . = ALIGN(8); - _eqspi = .; - } > qspi - - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = . ; - _szero = .; - *(.bss .bss.*) - *(COMMON) - . = ALIGN(4); - _ebss = . ; - _ezero = .; - end = .; - } > ram - - /* stack section */ - .stack (NOLOAD): - { - . = ALIGN(8); - _sstack = .; - . = . + STACK_SIZE; - . = ALIGN(8); - _estack = .; - } > ram - - . = ALIGN(4); - _end = . ; -} diff --git a/hw/bsp/samd51/boards/pyportal/board.cmake b/hw/bsp/samd51/boards/pyportal/board.cmake deleted file mode 100644 index 86d12ca24..000000000 --- a/hw/bsp/samd51/boards/pyportal/board.cmake +++ /dev/null @@ -1,10 +0,0 @@ -set(SAM_FAMILY samd51) - -set(JLINK_DEVICE ATSAMD51J19) -set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) - -function(update_board TARGET) - target_compile_definitions(${TARGET} PUBLIC - __SAMD51J19A__ - ) -endfunction() diff --git a/hw/bsp/samd51/boards/pyportal/board.h b/hw/bsp/samd51/boards/pyportal/board.h deleted file mode 100644 index ff04c900b..000000000 --- a/hw/bsp/samd51/boards/pyportal/board.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -// LED -#define LED_PIN (32+23) -#define LED_STATE_ON 1 - -// Button -#define BUTTON_PIN (32+22) // D2 -#define BUTTON_STATE_ACTIVE 0 - -// UART -#define UART_TX_PIN (32 + 13) -#define UART_RX_PIN (32 + 12) - -#ifdef __cplusplus - } -#endif - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd51/boards/pyportal/board.mk b/hw/bsp/samd51/boards/pyportal/board.mk deleted file mode 100644 index 811c5f4e3..000000000 --- a/hw/bsp/samd51/boards/pyportal/board.mk +++ /dev/null @@ -1,10 +0,0 @@ -SAM_FAMILY = samd51 - -CFLAGS += -D__SAMD51J19A__ - -LD_FILE = $(BOARD_PATH)/$(BOARD).ld - -# For flash-jlink target -JLINK_DEVICE = ATSAMD51J19 - -flash: flash-bossac diff --git a/hw/bsp/samd51/boards/pyportal/pyportal.ld b/hw/bsp/samd51/boards/pyportal/pyportal.ld deleted file mode 100644 index 1408c3018..000000000 --- a/hw/bsp/samd51/boards/pyportal/pyportal.ld +++ /dev/null @@ -1,166 +0,0 @@ -/** - * \file - * - * \brief Linker script for running in internal FLASH on the SAMD51G19A - * - * Copyright (c) 2017 Microchip Technology Inc. - * - * \asf_license_start - * - * \page License - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the Licence at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * \asf_license_stop - * - */ - - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -SEARCH_DIR(.) - -/* Memory Spaces Definitions */ -MEMORY -{ - rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 - bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 - qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 -} - -/* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; - -ENTRY(Reset_Handler) - -/* Section Definitions */ -SECTIONS -{ - .text : - { - . = ALIGN(4); - _sfixed = .; - KEEP(*(.vectors .vectors.*)) - *(.text .text.* .gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) - *(.rodata .rodata* .gnu.linkonce.r.*) - *(.ARM.extab* .gnu.linkonce.armextab.*) - - /* Support C constructors, and C destructors in both user code - and the C library. This also provides support for C++ code. */ - . = ALIGN(4); - KEEP(*(.init)) - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - - . = ALIGN(4); - _efixed = .; /* End of text section */ - } > rom - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - PROVIDE_HIDDEN (__exidx_start = .); - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > rom - PROVIDE_HIDDEN (__exidx_end = .); - - . = ALIGN(4); - _etext = .; - - .relocate : AT (_etext) - { - . = ALIGN(4); - _srelocate = .; - *(.ramfunc .ramfunc.*); - *(.data .data.*); - . = ALIGN(4); - _erelocate = .; - } > ram - - .bkupram (NOLOAD): - { - . = ALIGN(8); - _sbkupram = .; - *(.bkupram .bkupram.*); - . = ALIGN(8); - _ebkupram = .; - } > bkupram - - .qspi (NOLOAD): - { - . = ALIGN(8); - _sqspi = .; - *(.qspi .qspi.*); - . = ALIGN(8); - _eqspi = .; - } > qspi - - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = . ; - _szero = .; - *(.bss .bss.*) - *(COMMON) - . = ALIGN(4); - _ebss = . ; - _ezero = .; - end = .; - } > ram - - /* stack section */ - .stack (NOLOAD): - { - . = ALIGN(8); - _sstack = .; - . = . + STACK_SIZE; - . = ALIGN(8); - _estack = .; - } > ram - - . = ALIGN(4); - _end = . ; -} diff --git a/hw/bsp/samd51/boards/same54_xplained/board.cmake b/hw/bsp/samd51/boards/same54_xplained/board.cmake deleted file mode 100644 index 4d98205bc..000000000 --- a/hw/bsp/samd51/boards/same54_xplained/board.cmake +++ /dev/null @@ -1,10 +0,0 @@ -set(SAM_FAMILY same54) - -set(JLINK_DEVICE ATSAME54P20) -set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/same54p20a_flash.ld) - -function(update_board TARGET) - target_compile_definitions(${TARGET} PUBLIC - __SAME54P20A__ - ) -endfunction() diff --git a/hw/bsp/samd51/boards/same54_xplained/board.h b/hw/bsp/samd51/boards/same54_xplained/board.h deleted file mode 100644 index faaa52b8e..000000000 --- a/hw/bsp/samd51/boards/same54_xplained/board.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -// LED -#define LED_PIN PIN_PC18 -#define LED_STATE_ON 1 - -// Button: D5 -#define BUTTON_PIN PIN_PB31 -#define BUTTON_STATE_ACTIVE 0 - -// UART: SERCOM2 -//#define UART_TX_PIN 23 -//#define UART_RX_PIN 22 - -#ifdef __cplusplus - } -#endif - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd51/boards/same54_xplained/board.mk b/hw/bsp/samd51/boards/same54_xplained/board.mk deleted file mode 100644 index d10e9e34c..000000000 --- a/hw/bsp/samd51/boards/same54_xplained/board.mk +++ /dev/null @@ -1,9 +0,0 @@ -SAM_FAMILY = same54 - -CFLAGS += -D__SAME54P20A__ - -# All source paths should be relative to the top level. -LD_FILE = $(BOARD_PATH)/same54p20a_flash.ld - -# For flash-jlink target -JLINK_DEVICE = ATSAME54P20 diff --git a/hw/bsp/samd51/boards/same54_xplained/same54p20a_flash.ld b/hw/bsp/samd51/boards/same54_xplained/same54p20a_flash.ld deleted file mode 100644 index 8a9fd7d9f..000000000 --- a/hw/bsp/samd51/boards/same54_xplained/same54p20a_flash.ld +++ /dev/null @@ -1,166 +0,0 @@ -/** - * \file - * - * \brief Linker script for running in internal FLASH on the SAME54P20A - * - * Copyright (c) 2019 Microchip Technology Inc. - * - * \asf_license_start - * - * \page License - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the Licence at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * \asf_license_stop - * - */ - - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -SEARCH_DIR(.) - -/* Memory Spaces Definitions */ -MEMORY -{ - rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000 - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 - bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 - qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 -} - -/* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x10000; - -ENTRY(Reset_Handler) - -/* Section Definitions */ -SECTIONS -{ - .text : - { - . = ALIGN(4); - _sfixed = .; - KEEP(*(.vectors .vectors.*)) - *(.text .text.* .gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) - *(.rodata .rodata* .gnu.linkonce.r.*) - *(.ARM.extab* .gnu.linkonce.armextab.*) - - /* Support C constructors, and C destructors in both user code - and the C library. This also provides support for C++ code. */ - . = ALIGN(4); - KEEP(*(.init)) - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - - . = ALIGN(4); - _efixed = .; /* End of text section */ - } > rom - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - PROVIDE_HIDDEN (__exidx_start = .); - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > rom - PROVIDE_HIDDEN (__exidx_end = .); - - . = ALIGN(4); - _etext = .; - - .relocate : AT (_etext) - { - . = ALIGN(4); - _srelocate = .; - *(.ramfunc .ramfunc.*); - *(.data .data.*); - . = ALIGN(4); - _erelocate = .; - } > ram - - .bkupram (NOLOAD): - { - . = ALIGN(8); - _sbkupram = .; - *(.bkupram .bkupram.*); - . = ALIGN(8); - _ebkupram = .; - } > bkupram - - .qspi (NOLOAD): - { - . = ALIGN(8); - _sqspi = .; - *(.qspi .qspi.*); - . = ALIGN(8); - _eqspi = .; - } > qspi - - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = . ; - _szero = .; - *(.bss .bss.*) - *(COMMON) - . = ALIGN(4); - _ebss = . ; - _ezero = .; - } > ram - - /* stack section */ - .stack (NOLOAD): - { - . = ALIGN(8); - _sstack = .; - . = . + STACK_SIZE; - . = ALIGN(8); - _estack = .; - } > ram - - . = ALIGN(4); - _end = . ; - end = .; -} diff --git a/hw/bsp/samd51/boards/same54_xplained/same54p20a_sram.ld b/hw/bsp/samd51/boards/same54_xplained/same54p20a_sram.ld deleted file mode 100644 index c88617729..000000000 --- a/hw/bsp/samd51/boards/same54_xplained/same54p20a_sram.ld +++ /dev/null @@ -1,165 +0,0 @@ -/** - * \file - * - * \brief Linker script for running in internal SRAM on the SAME54P20A - * - * Copyright (c) 2019 Microchip Technology Inc. - * - * \asf_license_start - * - * \page License - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the Licence at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * \asf_license_stop - * - */ - - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -SEARCH_DIR(.) - -/* Memory Spaces Definitions */ -MEMORY -{ - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 - bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 - qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 -} - -/* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x10000; - -ENTRY(Reset_Handler) - -/* Section Definitions */ -SECTIONS -{ - .text : - { - . = ALIGN(4); - _sfixed = .; - KEEP(*(.vectors .vectors.*)) - *(.text .text.* .gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) - *(.rodata .rodata* .gnu.linkonce.r.*) - *(.ARM.extab* .gnu.linkonce.armextab.*) - - /* Support C constructors, and C destructors in both user code - and the C library. This also provides support for C++ code. */ - . = ALIGN(4); - KEEP(*(.init)) - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - - . = ALIGN(4); - _efixed = .; /* End of text section */ - } > ram - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - PROVIDE_HIDDEN (__exidx_start = .); - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > ram - PROVIDE_HIDDEN (__exidx_end = .); - - . = ALIGN(4); - _etext = .; - - .relocate : AT (_etext) - { - . = ALIGN(4); - _srelocate = .; - *(.ramfunc .ramfunc.*); - *(.data .data.*); - . = ALIGN(4); - _erelocate = .; - } > ram - - .bkupram (NOLOAD): - { - . = ALIGN(8); - _sbkupram = .; - *(.bkupram .bkupram.*); - . = ALIGN(8); - _ebkupram = .; - } > bkupram - - .qspi (NOLOAD): - { - . = ALIGN(8); - _sqspi = .; - *(.qspi .qspi.*); - . = ALIGN(8); - _eqspi = .; - } > qspi - - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = . ; - _szero = .; - *(.bss .bss.*) - *(COMMON) - . = ALIGN(4); - _ebss = . ; - _ezero = .; - } > ram - - /* stack section */ - .stack (NOLOAD): - { - . = ALIGN(8); - _sstack = .; - . = . + STACK_SIZE; - . = ALIGN(8); - _estack = .; - } > ram - - . = ALIGN(4); - _end = . ; - end = .; -} diff --git a/hw/bsp/samd51/family.c b/hw/bsp/samd51/family.c deleted file mode 100644 index abaee353b..000000000 --- a/hw/bsp/samd51/family.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "sam.h" -#include "bsp/board_api.h" -#include "board.h" - -// Suppress warning caused by mcu driver -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-qual" -#endif - -#include "hal_gpio.h" -#include "hal_init.h" -#include "hpl/gclk/hpl_gclk_base.h" -#include "hpl_mclk_config.h" - -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ - -/* Referenced GCLKs, should be initialized firstly */ -#define _GCLK_INIT_1ST 0xFFFFFFFF - -/* Not referenced GCLKs, initialized last */ -#define _GCLK_INIT_LAST (~_GCLK_INIT_1ST) - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB_0_Handler(void) { - tud_int_handler(0); -} - -void USB_1_Handler(void) { - tud_int_handler(0); -} - -void USB_2_Handler(void) { - tud_int_handler(0); -} - -void USB_3_Handler(void) { - tud_int_handler(0); -} - -//--------------------------------------------------------------------+ -// Implementation -//--------------------------------------------------------------------+ - -#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 - -#define MAX3421_SERCOM TU_XSTRCAT(SERCOM, MAX3421_SERCOM_ID) -#define MAX3421_EIC_Handler TU_XSTRCAT3(EIC_, MAX3421_INTR_EIC_ID, _Handler) - -static void max3421_init(void); -#endif - -void board_init(void) { - // Clock init ( follow hpl_init.c ) - hri_nvmctrl_set_CTRLA_RWS_bf(NVMCTRL, 0); - - _osc32kctrl_init_sources(); - _oscctrl_init_sources(); - _mclk_init(); -#if _GCLK_INIT_1ST - _gclk_init_generators_by_fref(_GCLK_INIT_1ST); -#endif - _oscctrl_init_referenced_generators(); - _gclk_init_generators_by_fref(_GCLK_INIT_LAST); - - // Update SystemCoreClock since it is hard coded with asf4 and not correct - // Init 1ms tick timer (samd SystemCoreClock may not correct) - SystemCoreClock = CONF_CPU_FREQUENCY; - SysTick_Config(CONF_CPU_FREQUENCY / 1000); - - // Led init - gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); - gpio_set_pin_level(LED_PIN, 0); - -#ifdef BUTTON_PIN - // Button init - gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); - gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP); -#endif - -#if CFG_TUSB_OS == OPT_OS_FREERTOS - // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB_0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_3_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); -#endif - - /* USB Clock init - * The USB module requires a GCLK_USB of 48 MHz ~ 0.25% clock - * for low speed and full speed operation. */ - hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN); - hri_mclk_set_AHBMASK_USB_bit(MCLK); - hri_mclk_set_APBBMASK_USB_bit(MCLK); - - // USB Pin Init - gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT); - gpio_set_pin_level(PIN_PA24, false); - gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF); - gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT); - gpio_set_pin_level(PIN_PA25, false); - gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF); - - gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM); - gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP); - -#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 - max3421_init(); -#endif -} - -void board_init_after_tusb(void) { -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) { - gpio_set_pin_level(LED_PIN, state); -} - -uint32_t board_button_read(void) { - // button is active low - #ifdef BUTTON_PIN - return gpio_get_pin_level(BUTTON_PIN) ? 0 : 1; - #else - return 0; - #endif -} - -size_t board_get_unique_id(uint8_t id[], size_t max_len) { - (void) max_len; - - uint32_t did_addr[4] = {0x008061FC, 0x00806010, 0x00806014, 0x00806018}; - - for (int i = 0; i < 4; i++) { - uint32_t did = *((uint32_t const*) did_addr[i]); - did = TU_BSWAP32(did); // swap endian to match samd51 uf2 bootloader - memcpy(id + i * 4, &did, 4); - } - - return 16; -} - -int board_uart_read(uint8_t* buf, int len) { - (void) buf; - (void) len; - return 0; -} - -int board_uart_write(void const* buf, int len) { - (void) buf; - (void) len; - return 0; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; - -void SysTick_Handler(void) { - system_ticks++; -} - -uint32_t board_millis(void) { - return system_ticks; -} - -#if 0 -/* Initialize SERCOM2 for 115200 bps 8N1 using a 48 MHz clock */ -static inline void uart_init(void) { - gpio_set_pin_function(PIN_PB24, PINMUX_PB24D_SERCOM2_PAD1); - gpio_set_pin_function(PIN_PB25, PINMUX_PB25D_SERCOM2_PAD0); - - MCLK->APBBMASK.bit.SERCOM2_ = 1; - GCLK->PCHCTRL[SERCOM2_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN; - - BOARD_SERCOM->USART.CTRLA.bit.SWRST = 1; /* reset and disable SERCOM -> enable configuration */ - while (BOARD_SERCOM->USART.SYNCBUSY.bit.SWRST); - - BOARD_SERCOM->USART.CTRLA.reg = - SERCOM_USART_CTRLA_SAMPR(0) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ - SERCOM_USART_CTRLA_SAMPA(0) | /* 16x over sampling */ - SERCOM_USART_CTRLA_FORM(0) | /* 0x0 USART frame, 0x1 USART frame with parity, ... */ - SERCOM_USART_CTRLA_DORD | /* LSB first */ - SERCOM_USART_CTRLA_MODE(1) | /* 0x0 USART with external clock, 0x1 USART with internal clock */ - SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ - SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ - - BOARD_SERCOM->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ - SERCOM_USART_CTRLB_TXEN | /* transmitter enabled */ - SERCOM_USART_CTRLB_RXEN; /* receiver enabled */ - // BOARD_SERCOM->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(0) | SERCOM_USART_BAUD_FRAC_BAUD(26); /* 48000000/(16*115200) = 26.041666667 */ - BOARD_SERCOM->USART.BAUD.reg = SERCOM_USART_BAUD_BAUD(63019); /* 65536*(1−16*115200/48000000) */ - - BOARD_SERCOM->USART.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ - while (BOARD_SERCOM->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ -} - -static inline void uart_send_buffer(uint8_t const* text, size_t len) { - for (size_t i = 0; i < len; ++i) { - BOARD_SERCOM->USART.DATA.reg = text[i]; - while ((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); - } -} - -static inline void uart_send_str(const char* text) { - while (*text) { - BOARD_SERCOM->USART.DATA.reg = *text++; - while ((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); - } -} - -#endif - -#endif - -//--------------------------------------------------------------------+ -// API: SPI transfer with MAX3421E, must be implemented by application -//--------------------------------------------------------------------+ -#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 - -static void max3421_init(void) { - //------------- SPI Init -------------// - - // MAX3421E max SPI clock is 26MHz however SAMD can only work reliably at 12 Mhz - uint32_t const baudrate = 12000000u; - - struct { - volatile uint32_t* mck_apb; - uint32_t mask; - uint8_t gclk_id_core; - uint8_t gclk_id_slow; - } const sercom_clock[] = { - { &MCLK->APBAMASK.reg, MCLK_APBAMASK_SERCOM0, SERCOM0_GCLK_ID_CORE, SERCOM0_GCLK_ID_SLOW }, - { &MCLK->APBAMASK.reg, MCLK_APBAMASK_SERCOM1, SERCOM1_GCLK_ID_CORE, SERCOM1_GCLK_ID_SLOW }, - { &MCLK->APBBMASK.reg, MCLK_APBBMASK_SERCOM2, SERCOM2_GCLK_ID_CORE, SERCOM2_GCLK_ID_SLOW }, - { &MCLK->APBBMASK.reg, MCLK_APBBMASK_SERCOM3, SERCOM3_GCLK_ID_CORE, SERCOM3_GCLK_ID_SLOW }, - { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM4, SERCOM4_GCLK_ID_CORE, SERCOM4_GCLK_ID_SLOW }, - { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM5, SERCOM5_GCLK_ID_CORE, SERCOM5_GCLK_ID_SLOW }, - #ifdef SERCOM6_GCLK_ID_CORE - { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM6, SERCOM6_GCLK_ID_CORE, SERCOM6_GCLK_ID_SLOW }, - #endif - #ifdef SERCOM7_GCLK_ID_CORE - { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM7, SERCOM7_GCLK_ID_CORE, SERCOM7_GCLK_ID_SLOW }, - #endif - }; - - Sercom* sercom = MAX3421_SERCOM; - - // Enable the APB clock for SERCOM - *sercom_clock[MAX3421_SERCOM_ID].mck_apb |= sercom_clock[MAX3421_SERCOM_ID].mask; - - // Configure GCLK for SERCOM - GCLK->PCHCTRL[sercom_clock[MAX3421_SERCOM_ID].gclk_id_core].reg = - GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); - GCLK->PCHCTRL[sercom_clock[MAX3421_SERCOM_ID].gclk_id_slow].reg = - GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); - - // Disable the SPI module - sercom->SPI.CTRLA.bit.ENABLE = 0; - - // Reset the SPI module - sercom->SPI.CTRLA.bit.SWRST = 1; - while (sercom->SPI.SYNCBUSY.bit.SWRST); - - // Set up SPI in master mode, MSB first, SPI mode 0 - sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_DOPO(MAX3421_TX_PAD) | SERCOM_SPI_CTRLA_DIPO(MAX3421_RX_PAD) | - SERCOM_SPI_CTRLA_MODE(3); - - sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(0) | SERCOM_SPI_CTRLB_RXEN; - while (sercom->SPI.SYNCBUSY.bit.CTRLB == 1); - - // Set the baud rate - uint8_t baud_reg = (uint8_t) (SystemCoreClock / (2 * baudrate)); - if (baud_reg) { - baud_reg--; - } - - sercom->SPI.BAUD.reg = baud_reg; - - // Configure PA12 as MOSI (PAD0), PA13 as SCK (PAD1), PA14 as MISO (PAD2), function C (sercom) - gpio_set_pin_direction(MAX3421_SCK_PIN, GPIO_DIRECTION_OUT); - gpio_set_pin_pull_mode(MAX3421_SCK_PIN, GPIO_PULL_OFF); - gpio_set_pin_function(MAX3421_SCK_PIN, MAX3421_SERCOM_FUNCTION); - - gpio_set_pin_direction(MAX3421_MOSI_PIN, GPIO_DIRECTION_OUT); - gpio_set_pin_pull_mode(MAX3421_MOSI_PIN, GPIO_PULL_OFF); - gpio_set_pin_function(MAX3421_MOSI_PIN, MAX3421_SERCOM_FUNCTION); - - gpio_set_pin_direction(MAX3421_MISO_PIN, GPIO_DIRECTION_IN); - gpio_set_pin_pull_mode(MAX3421_MISO_PIN, GPIO_PULL_OFF); - gpio_set_pin_function(MAX3421_MISO_PIN, MAX3421_SERCOM_FUNCTION); - - // CS pin - gpio_set_pin_direction(MAX3421_CS_PIN, GPIO_DIRECTION_OUT); - gpio_set_pin_level(MAX3421_CS_PIN, 1); - - // Enable the SPI module - sercom->SPI.CTRLA.bit.ENABLE = 1; - while (sercom->SPI.SYNCBUSY.bit.ENABLE) {} - - //------------- External Interrupt -------------// - - // Enable the APB clock for EIC (External Interrupt Controller) - MCLK->APBAMASK.reg |= MCLK_APBAMASK_EIC; - - // Configure GCLK for EIC - GCLK->PCHCTRL[EIC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); - - // Configure PA20 as an input with function A (external interrupt) - gpio_set_pin_direction(MAX3421_INTR_PIN, GPIO_DIRECTION_IN); - gpio_set_pin_pull_mode(MAX3421_INTR_PIN, GPIO_PULL_UP); - gpio_set_pin_function(MAX3421_INTR_PIN, 0); - - // Disable EIC - EIC->CTRLA.bit.ENABLE = 0; - while (EIC->SYNCBUSY.bit.ENABLE); - - // Configure EIC to trigger on falling edge - volatile uint32_t* eic_config; - uint8_t sense_shift; - if (MAX3421_INTR_EIC_ID < 8) { - eic_config = &EIC->CONFIG[0].reg; - sense_shift = MAX3421_INTR_EIC_ID * 4; - } else { - eic_config = &EIC->CONFIG[1].reg; - sense_shift = (MAX3421_INTR_EIC_ID - 8) * 4; - } - - *eic_config &= ~(7 << sense_shift); - *eic_config |= 2 << sense_shift; - -#if CFG_TUSB_OS == OPT_OS_FREERTOS - // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(EIC_0_IRQn + MAX3421_INTR_EIC_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); -#endif - - // Enable External Interrupt - EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << MAX3421_INTR_EIC_ID); - - // Enable EIC - EIC->CTRLA.bit.ENABLE = 1; - while (EIC->SYNCBUSY.bit.ENABLE); -} - -void MAX3421_EIC_Handler(void) { - // Clear the interrupt flag - EIC->INTFLAG.reg = EIC_INTFLAG_EXTINT(1 << MAX3421_INTR_EIC_ID); - - // Call the TinyUSB interrupt handler - tuh_int_handler(1, true); -} - -// API to enable/disable MAX3421 INTR pin interrupt -void tuh_max3421_int_api(uint8_t rhport, bool enabled) { - (void) rhport; - - const IRQn_Type irq = EIC_0_IRQn + MAX3421_INTR_EIC_ID; - if (enabled) { - NVIC_EnableIRQ(irq); - } else { - NVIC_DisableIRQ(irq); - } -} - -// API to control MAX3421 SPI CS -void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { - (void) rhport; - gpio_set_pin_level(MAX3421_CS_PIN, active ? 0 : 1); -} - -// API to transfer data with MAX3421 SPI -// Either tx_buf or rx_buf can be NULL, which means transfer is write or read only -bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { - (void) rhport; - - Sercom* sercom = MAX3421_SERCOM; - - for (size_t count = 0; count < xfer_bytes; count++) { - // Wait for the transmit buffer to be empty - while (!sercom->SPI.INTFLAG.bit.DRE); - - // Write data to be transmitted - uint8_t data = 0x00; - if (tx_buf) { - data = tx_buf[count]; - } - - sercom->SPI.DATA.reg = (uint32_t) data; - - // Wait for the receive buffer to be filled - while (!sercom->SPI.INTFLAG.bit.RXC); - - // Read received data - data = (uint8_t) sercom->SPI.DATA.reg; - if (rx_buf) { - rx_buf[count] = data; - } - } - - // wait for bus idle and clear flags - while (!(sercom->SPI.INTFLAG.reg & (SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE))); - sercom->SPI.INTFLAG.reg = SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE; - - return true; -} - -#endif - -void HardFault_Handler(void) { - __BKPT(0); - while (1); -} diff --git a/hw/bsp/samd51/family.cmake b/hw/bsp/samd51/family.cmake deleted file mode 100644 index 6d64a5fe4..000000000 --- a/hw/bsp/samd51/family.cmake +++ /dev/null @@ -1,109 +0,0 @@ -include_guard() - -include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) - -set(SDK_DIR ${TOP}/hw/mcu/microchip/${SAM_FAMILY}) -set(CMSIS_5 ${TOP}/lib/CMSIS_5) - -# toolchain set up -set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") -set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) - -set(FAMILY_MCUS SAMD51 SAME54 CACHE INTERNAL "") -set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -c \"set CHIPNAME samd51\" -f target/atsame5x.cfg") - -#------------------------------------ -# BOARD_TARGET -#------------------------------------ -# only need to be built ONCE for all examples -function(add_board_target BOARD_TARGET) - if (TARGET ${BOARD_TARGET}) - return() - endif () - - set(LD_FILE_Clang ${LD_FILE_GNU}) - if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) - message(FATAL_ERROR "LD_FILE_${CMAKE_C_COMPILER_ID} not defined") - endif () - - set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_${SAM_FAMILY}.c) - set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - - add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/gcc/system_${SAM_FAMILY}.c - ${SDK_DIR}/hal/src/hal_atomic.c - ${SDK_DIR}/hpl/gclk/hpl_gclk.c - ${SDK_DIR}/hpl/mclk/hpl_mclk.c - ${SDK_DIR}/hpl/osc32kctrl/hpl_osc32kctrl.c - ${SDK_DIR}/hpl/oscctrl/hpl_oscctrl.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${SDK_DIR} - ${SDK_DIR}/config - ${SDK_DIR}/include - ${SDK_DIR}/hal/include - ${SDK_DIR}/hal/utils/include - ${SDK_DIR}/hpl/port - ${SDK_DIR}/hri - ${CMSIS_5}/CMSIS/Core/Include - ) - - update_board(${BOARD_TARGET}) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - --specs=nosys.specs --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_Clang}" - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () -endfunction() - - -#------------------------------------ -# Functions -#------------------------------------ -function(family_configure_example TARGET RTOS) - family_configure_common(${TARGET} ${RTOS}) - - # Board target - add_board_target(board_${BOARD}) - - #---------- Port Specific ---------- - # These files are built for each example since it depends on example's tusb_config.h - target_sources(${TARGET} PUBLIC - # BSP - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c - ) - target_include_directories(${TARGET} PUBLIC - # family, hw, board - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} - ) - - # Add TinyUSB target and port source - family_add_tinyusb(${TARGET} OPT_MCU_SAMD51 ${RTOS}) - target_sources(${TARGET}-tinyusb PUBLIC - ${TOP}/src/portable/microchip/samd/dcd_samd.c - ) - target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) - - # Link dependencies - target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) - - # Flashing - family_add_bin_hex(${TARGET}) - family_flash_jlink(${TARGET}) - #family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) -endfunction() diff --git a/hw/bsp/samd51/family.mk b/hw/bsp/samd51/family.mk deleted file mode 100644 index 9b1a23db4..000000000 --- a/hw/bsp/samd51/family.mk +++ /dev/null @@ -1,51 +0,0 @@ -UF2_FAMILY_ID = 0x55114460 - -include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= cortex-m4 - -SDK_DIR = hw/mcu/microchip/${SAM_FAMILY} - -CFLAGS += \ - -flto \ - -DCFG_TUSB_MCU=OPT_MCU_SAMD51 - -# SAM driver is flooded with -Wcast-qual which slow down complication significantly -CFLAGS_SKIP += -Wcast-qual - -LDFLAGS_GCC += \ - -nostdlib -nostartfiles \ - --specs=nosys.specs --specs=nano.specs - -SRC_C += \ - src/portable/microchip/samd/dcd_samd.c \ - ${SDK_DIR}/gcc/gcc/startup_${SAM_FAMILY}.c \ - ${SDK_DIR}/gcc/system_${SAM_FAMILY}.c \ - ${SDK_DIR}/hpl/gclk/hpl_gclk.c \ - ${SDK_DIR}/hpl/mclk/hpl_mclk.c \ - ${SDK_DIR}/hpl/osc32kctrl/hpl_osc32kctrl.c \ - ${SDK_DIR}/hpl/oscctrl/hpl_oscctrl.c \ - ${SDK_DIR}/hal/src/hal_atomic.c - -INC += \ - $(TOP)/$(BOARD_PATH) \ - $(TOP)/${SDK_DIR} \ - $(TOP)/${SDK_DIR}/config \ - $(TOP)/${SDK_DIR}/include \ - $(TOP)/${SDK_DIR}/hal/include \ - $(TOP)/${SDK_DIR}/hal/utils/include \ - $(TOP)/${SDK_DIR}/hpl/port \ - $(TOP)/${SDK_DIR}/hri \ - $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ - -# flash using bossac at least version 1.8 -# can be found in arduino15/packages/arduino/tools/bossac/ -# Add it to your PATH or change BOSSAC variable to match your installation -BOSSAC = bossac - -flash-bossac: $(BUILD)/$(PROJECT).bin - @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) - $(BOSSAC) --port=$(SERIAL) -U -i --offset=0x4000 -e -w $^ -R - -# flash using edbg from https://github.com/ataradov/edbg -flash-edbg: $(BUILD)/$(PROJECT).bin - edbg --verbose -t $(MCU) -pv -f $< diff --git a/hw/bsp/samd5x_e5x/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/samd5x_e5x/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..a283560fe --- /dev/null +++ b/hw/bsp/samd5x_e5x/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "sam.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*6*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 3 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<XOSCCTRL[1].reg = + OSCCTRL_XOSCCTRL_STARTUP(6) | // 1,953 ms + OSCCTRL_XOSCCTRL_RUNSTDBY | + OSCCTRL_XOSCCTRL_ENALC | + OSCCTRL_XOSCCTRL_IMULT(4) | + OSCCTRL_XOSCCTRL_IPTAT(3) | + OSCCTRL_XOSCCTRL_XTALEN | + OSCCTRL_XOSCCTRL_ENABLE; + while(0 == OSCCTRL->STATUS.bit.XOSCRDY1); + + OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(3) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC1_Val); /* pre-scaler = 8, input = XOSC1 */ + OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(39); /* multiply by 40 -> 80 MHz */ + OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; + while(0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL0 to be ready */ + + OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(7) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC1_Val); /* pre-scaler = 16, input = XOSC1 */ + OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(47); /* multiply by 48 -> 48 MHz */ + OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; + while(0 == OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL1 to be ready */ +#else // HWREV >= 1 + /* configure XOSC0 for a 16MHz crystal connected to XIN0/XOUT0 */ + OSCCTRL->XOSCCTRL[0].reg = + OSCCTRL_XOSCCTRL_STARTUP(6) | // 1,953 ms + OSCCTRL_XOSCCTRL_RUNSTDBY | + OSCCTRL_XOSCCTRL_ENALC | + OSCCTRL_XOSCCTRL_IMULT(4) | + OSCCTRL_XOSCCTRL_IPTAT(3) | + OSCCTRL_XOSCCTRL_XTALEN | + OSCCTRL_XOSCCTRL_ENABLE; + while (0 == OSCCTRL->STATUS.bit.XOSCRDY0); + + OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(3) | OSCCTRL_DPLLCTRLB_REFCLK( + OSCCTRL_DPLLCTRLB_REFCLK_XOSC0_Val); /* pre-scaler = 8, input = XOSC1 */ + OSCCTRL->Dpll[0].DPLLRATIO.reg = + OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(39); /* multiply by 40 -> 80 MHz */ + OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; + while (0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL0 to be ready */ + + OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(7) | OSCCTRL_DPLLCTRLB_REFCLK( + OSCCTRL_DPLLCTRLB_REFCLK_XOSC0_Val); /* pre-scaler = 16, input = XOSC1 */ + OSCCTRL->Dpll[1].DPLLRATIO.reg = + OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(47); /* multiply by 48 -> 48 MHz */ + OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; + while (0 == OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL1 to be ready */ +#endif // HWREV + + /* configure clock-generator 0 to use DPLL0 as source -> GCLK0 is used for the core */ + GCLK->GENCTRL[0].reg = + GCLK_GENCTRL_DIV(0) | + GCLK_GENCTRL_RUNSTDBY | + GCLK_GENCTRL_GENEN | + GCLK_GENCTRL_SRC_DPLL0 | /* DPLL0 */ + GCLK_GENCTRL_IDC; + while (1 == GCLK->SYNCBUSY.bit.GENCTRL0); /* wait for the synchronization between clock domains to be complete */ + + /* configure clock-generator 1 to use DPLL1 as source -> for use with some peripheral */ + GCLK->GENCTRL[1].reg = + GCLK_GENCTRL_DIV(0) | + GCLK_GENCTRL_RUNSTDBY | + GCLK_GENCTRL_GENEN | + GCLK_GENCTRL_SRC_DPLL1 | + GCLK_GENCTRL_IDC; + while (1 == GCLK->SYNCBUSY.bit.GENCTRL1); /* wait for the synchronization between clock domains to be complete */ + + /* configure clock-generator 2 to use DPLL0 as source -> for use with SERCOM */ + GCLK->GENCTRL[2].reg = + GCLK_GENCTRL_DIV(1) | /* 80MHz */ + GCLK_GENCTRL_RUNSTDBY | + GCLK_GENCTRL_GENEN | + GCLK_GENCTRL_SRC_DPLL0 | + GCLK_GENCTRL_IDC; + while (1 == GCLK->SYNCBUSY.bit.GENCTRL2); /* wait for the synchronization between clock domains to be complete */ +} + +static inline void uart_init(void) { +#if HWREV < 3 + /* configure SERCOM5 on PB02 */ + PORT->Group[1].WRCONFIG.reg = + PORT_WRCONFIG_WRPINCFG | + PORT_WRCONFIG_WRPMUX | + PORT_WRCONFIG_PMUX(3) | /* function D */ + PORT_WRCONFIG_DRVSTR | + PORT_WRCONFIG_PINMASK(0x0004) | /* PB02 */ + PORT_WRCONFIG_PMUXEN; + + MCLK->APBDMASK.bit.SERCOM5_ = 1; + GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg = + GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; /* setup SERCOM to use GLCK2 -> 80MHz */ + + SERCOM5->USART.CTRLA.reg = 0x00; /* disable SERCOM -> enable config */ + while (SERCOM5->USART.SYNCBUSY.bit.ENABLE); + + SERCOM5->USART.CTRLA.reg = /* CMODE = 0 -> async, SAMPA = 0, FORM = 0 -> USART frame, SMPR = 0 -> arithmetic baud rate */ + SERCOM_USART_CTRLA_SAMPR(1) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ + // SERCOM_USART_CTRLA_FORM(0) | /* 0 = USART Frame, 2 = LIN Master */ + SERCOM_USART_CTRLA_DORD | /* LSB first */ + SERCOM_USART_CTRLA_MODE(1) | /* 0 = Asynchronous, 1 = USART with internal clock */ + SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ + SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ + + SERCOM5->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ + SERCOM_USART_CTRLB_TXEN; /* transmitter enabled */ + SERCOM5->USART.CTRLC.reg = 0x00; + // 21.701388889 @ baud rate of 230400 bit/s, table 33-2, p 918 of DS60001507E + SERCOM5->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(7) | SERCOM_USART_BAUD_FRAC_BAUD(21); + +// SERCOM5->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC; + SERCOM5->SPI.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ + while (SERCOM5->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ +#else + /* configure SERCOM0 on PA08 */ + PORT->Group[0].WRCONFIG.reg = + PORT_WRCONFIG_WRPINCFG | + PORT_WRCONFIG_WRPMUX | + PORT_WRCONFIG_PMUX(2) | /* function C */ + PORT_WRCONFIG_DRVSTR | + PORT_WRCONFIG_PINMASK(0x0100) | /* PA08 */ + PORT_WRCONFIG_PMUXEN; + + MCLK->APBAMASK.bit.SERCOM0_ = 1; + GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; /* setup SERCOM to use GLCK2 -> 80MHz */ + + SERCOM0->USART.CTRLA.reg = 0x00; /* disable SERCOM -> enable config */ + while(SERCOM0->USART.SYNCBUSY.bit.ENABLE); + + SERCOM0->USART.CTRLA.reg = /* CMODE = 0 -> async, SAMPA = 0, FORM = 0 -> USART frame, SMPR = 0 -> arithmetic baud rate */ + SERCOM_USART_CTRLA_SAMPR(1) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ + // SERCOM_USART_CTRLA_FORM(0) | /* 0 = USART Frame, 2 = LIN Master */ + SERCOM_USART_CTRLA_DORD | /* LSB first */ + SERCOM_USART_CTRLA_MODE(1) | /* 0 = Asynchronous, 1 = USART with internal clock */ + SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ + SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ + + SERCOM0->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ + SERCOM_USART_CTRLB_TXEN; /* transmitter enabled */ + SERCOM0->USART.CTRLC.reg = 0x00; + // 21.701388889 @ baud rate of 230400 bit/s, table 33-2, p 918 of DS60001507E + SERCOM0->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(7) | SERCOM_USART_BAUD_FRAC_BAUD(21); + + // SERCOM0->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC; + SERCOM0->SPI.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ + while(SERCOM0->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ +#endif +} +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd5x_e5x/boards/d5035_01/board.mk b/hw/bsp/samd5x_e5x/boards/d5035_01/board.mk new file mode 100644 index 000000000..4aa6b89fe --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/d5035_01/board.mk @@ -0,0 +1,21 @@ +SAM_FAMILY = same51 + +HWREV ?= 1 + +CFLAGS += \ + -D__SAME51J19A__ \ + -DCONF_CPU_FREQUENCY=80000000 \ + -DCONF_GCLK_USB_FREQUENCY=48000000 \ + -DD5035_01=1 \ + -DBOARD_NAME="\"D5035-01\"" \ + -DSVC_Handler=SVCall_Handler \ + -DHWREV=$(HWREV) + +# All source paths should be relative to the top level. +LD_FILE = $(BOARD_PATH)/same51j19a_flash.ld + +# For flash-jlink target +JLINK_DEVICE = ATSAME51J19 + +# flash using jlink +flash: flash-jlink diff --git a/hw/bsp/samd5x_e5x/boards/d5035_01/same51j19a_flash.ld b/hw/bsp/samd5x_e5x/boards/d5035_01/same51j19a_flash.ld new file mode 100644 index 000000000..59afb604b --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/d5035_01/same51j19a_flash.ld @@ -0,0 +1,166 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAME51J19A + * + * Copyright (c) 2019 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 + bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 + qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000; + +ENTRY(Reset_Handler) + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + .bkupram (NOLOAD): + { + . = ALIGN(8); + _sbkupram = .; + *(.bkupram .bkupram.*); + . = ALIGN(8); + _ebkupram = .; + } > bkupram + + .qspi (NOLOAD): + { + . = ALIGN(8); + _sqspi = .; + *(.qspi .qspi.*); + . = ALIGN(8); + _eqspi = .; + } > qspi + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; + end = .; +} diff --git a/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.cmake b/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.cmake new file mode 100644 index 000000000..86d12ca24 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.cmake @@ -0,0 +1,10 @@ +set(SAM_FAMILY samd51) + +set(JLINK_DEVICE ATSAMD51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD51J19A__ + ) +endfunction() diff --git a/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.h b/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.h new file mode 100644 index 000000000..83de04266 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.h @@ -0,0 +1,67 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define _PINNUM(port, pin) ((port)*32 + (pin)) + +// LED +#define LED_PIN 23 +#define LED_STATE_ON 1 + +// Button +#define BUTTON_PIN 16 // D5 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_TX_PIN (32 + 17) +#define UART_RX_PIN (32 + 16) + +// SPI for USB host shield +#define MAX3421_SERCOM_ID 1 // SERCOM2 +#define MAX3421_SERCOM_FUNCTION 2 // function C + +#define MAX3421_SCK_PIN _PINNUM(0, 17) +#define MAX3421_MOSI_PIN _PINNUM(1, 23) +#define MAX3421_MISO_PIN _PINNUM(1, 22) +#define MAX3421_TX_PAD 2 // MOSI = PAD_3, SCK = PAD_1 +#define MAX3421_RX_PAD 2 // MISO = PAD_2 + +#define MAX3421_CS_PIN 20 // D10 + +#define MAX3421_INTR_PIN 19 // D9 +#define MAX3421_INTR_EIC_ID 3 // EIC3 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.mk b/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.mk new file mode 100644 index 000000000..811c5f4e3 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.mk @@ -0,0 +1,10 @@ +SAM_FAMILY = samd51 + +CFLAGS += -D__SAMD51J19A__ + +LD_FILE = $(BOARD_PATH)/$(BOARD).ld + +# For flash-jlink target +JLINK_DEVICE = ATSAMD51J19 + +flash: flash-bossac diff --git a/hw/bsp/samd5x_e5x/boards/feather_m4_express/feather_m4_express.ld b/hw/bsp/samd5x_e5x/boards/feather_m4_express/feather_m4_express.ld new file mode 100644 index 000000000..1408c3018 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/feather_m4_express/feather_m4_express.ld @@ -0,0 +1,166 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAMD51G19A + * + * Copyright (c) 2017 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 + bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 + qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; + +ENTRY(Reset_Handler) + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + .bkupram (NOLOAD): + { + . = ALIGN(8); + _sbkupram = .; + *(.bkupram .bkupram.*); + . = ALIGN(8); + _ebkupram = .; + } > bkupram + + .qspi (NOLOAD): + { + . = ALIGN(8); + _sqspi = .; + *(.qspi .qspi.*); + . = ALIGN(8); + _eqspi = .; + } > qspi + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + end = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; +} diff --git a/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.cmake b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.cmake new file mode 100644 index 000000000..86d12ca24 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.cmake @@ -0,0 +1,10 @@ +set(SAM_FAMILY samd51) + +set(JLINK_DEVICE ATSAMD51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD51J19A__ + ) +endfunction() diff --git a/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.h b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.h new file mode 100644 index 000000000..272315771 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.h @@ -0,0 +1,50 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PIN 22 +#define LED_STATE_ON 1 + +// Button +#define BUTTON_PIN 18 // D5 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_TX_PIN 16 +#define UART_RX_PIN 17 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.mk b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.mk new file mode 100644 index 000000000..eba7070c1 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.mk @@ -0,0 +1,11 @@ +SAM_FAMILY = samd51 + +CFLAGS += -D__SAMD51J19A__ + +# All source paths should be relative to the top level. +LD_FILE = $(BOARD_PATH)/$(BOARD).ld + +# For flash-jlink target +JLINK_DEVICE = ATSAMD51J19 + +flash: flash-bossac diff --git a/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/itsybitsy_m4.ld b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/itsybitsy_m4.ld new file mode 100644 index 000000000..1408c3018 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/itsybitsy_m4.ld @@ -0,0 +1,166 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAMD51G19A + * + * Copyright (c) 2017 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 + bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 + qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; + +ENTRY(Reset_Handler) + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + .bkupram (NOLOAD): + { + . = ALIGN(8); + _sbkupram = .; + *(.bkupram .bkupram.*); + . = ALIGN(8); + _ebkupram = .; + } > bkupram + + .qspi (NOLOAD): + { + . = ALIGN(8); + _sqspi = .; + *(.qspi .qspi.*); + . = ALIGN(8); + _eqspi = .; + } > qspi + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + end = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; +} diff --git a/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.cmake b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.cmake new file mode 100644 index 000000000..86d12ca24 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.cmake @@ -0,0 +1,10 @@ +set(SAM_FAMILY samd51) + +set(JLINK_DEVICE ATSAMD51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD51J19A__ + ) +endfunction() diff --git a/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.h b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.h new file mode 100644 index 000000000..b3b80db89 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.h @@ -0,0 +1,66 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PIN 16 +#define LED_STATE_ON 1 + +// Button: D5 +#define BUTTON_PIN (32+14) +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_TX_PIN 23 +#define UART_RX_PIN 22 + +// SPI for USB host shield +#define MAX3421_SERCOM_ID 2 // SERCOM2 +#define MAX3421_SERCOM_FUNCTION 2 // function C + +#define MAX3421_SCK_PIN 13 +#define MAX3421_MOSI_PIN 12 +#define MAX3421_MISO_PIN 14 +#define MAX3421_TX_PAD 0 // MOSI = PAD_0, SCK = PAD_1 +#define MAX3421_RX_PAD 2 // MISO = PAD_2 + +#define MAX3421_CS_PIN 18 // D10 + +#define MAX3421_INTR_PIN 20 // D9 +#define MAX3421_INTR_EIC_ID 4 // EIC4 + + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.mk b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.mk new file mode 100644 index 000000000..eba7070c1 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.mk @@ -0,0 +1,11 @@ +SAM_FAMILY = samd51 + +CFLAGS += -D__SAMD51J19A__ + +# All source paths should be relative to the top level. +LD_FILE = $(BOARD_PATH)/$(BOARD).ld + +# For flash-jlink target +JLINK_DEVICE = ATSAMD51J19 + +flash: flash-bossac diff --git a/hw/bsp/samd5x_e5x/boards/metro_m4_express/metro_m4_express.ld b/hw/bsp/samd5x_e5x/boards/metro_m4_express/metro_m4_express.ld new file mode 100644 index 000000000..1408c3018 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/metro_m4_express/metro_m4_express.ld @@ -0,0 +1,166 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAMD51G19A + * + * Copyright (c) 2017 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 + bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 + qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; + +ENTRY(Reset_Handler) + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + .bkupram (NOLOAD): + { + . = ALIGN(8); + _sbkupram = .; + *(.bkupram .bkupram.*); + . = ALIGN(8); + _ebkupram = .; + } > bkupram + + .qspi (NOLOAD): + { + . = ALIGN(8); + _sqspi = .; + *(.qspi .qspi.*); + . = ALIGN(8); + _eqspi = .; + } > qspi + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + end = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; +} diff --git a/hw/bsp/samd5x_e5x/boards/pybadge/board.cmake b/hw/bsp/samd5x_e5x/boards/pybadge/board.cmake new file mode 100644 index 000000000..86d12ca24 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/pybadge/board.cmake @@ -0,0 +1,10 @@ +set(SAM_FAMILY samd51) + +set(JLINK_DEVICE ATSAMD51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD51J19A__ + ) +endfunction() diff --git a/hw/bsp/samd5x_e5x/boards/pybadge/board.h b/hw/bsp/samd5x_e5x/boards/pybadge/board.h new file mode 100644 index 000000000..4629643fd --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/pybadge/board.h @@ -0,0 +1,50 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PIN 23 +#define LED_STATE_ON 1 + +// Button +#define BUTTON_PIN 16 // D5 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_TX_PIN (32 + 17) +#define UART_RX_PIN (32 + 16) + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd5x_e5x/boards/pybadge/board.mk b/hw/bsp/samd5x_e5x/boards/pybadge/board.mk new file mode 100644 index 000000000..811c5f4e3 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/pybadge/board.mk @@ -0,0 +1,10 @@ +SAM_FAMILY = samd51 + +CFLAGS += -D__SAMD51J19A__ + +LD_FILE = $(BOARD_PATH)/$(BOARD).ld + +# For flash-jlink target +JLINK_DEVICE = ATSAMD51J19 + +flash: flash-bossac diff --git a/hw/bsp/samd5x_e5x/boards/pybadge/pybadge.ld b/hw/bsp/samd5x_e5x/boards/pybadge/pybadge.ld new file mode 100644 index 000000000..1408c3018 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/pybadge/pybadge.ld @@ -0,0 +1,166 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAMD51G19A + * + * Copyright (c) 2017 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 + bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 + qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; + +ENTRY(Reset_Handler) + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + .bkupram (NOLOAD): + { + . = ALIGN(8); + _sbkupram = .; + *(.bkupram .bkupram.*); + . = ALIGN(8); + _ebkupram = .; + } > bkupram + + .qspi (NOLOAD): + { + . = ALIGN(8); + _sqspi = .; + *(.qspi .qspi.*); + . = ALIGN(8); + _eqspi = .; + } > qspi + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + end = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; +} diff --git a/hw/bsp/samd5x_e5x/boards/pyportal/board.cmake b/hw/bsp/samd5x_e5x/boards/pyportal/board.cmake new file mode 100644 index 000000000..86d12ca24 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/pyportal/board.cmake @@ -0,0 +1,10 @@ +set(SAM_FAMILY samd51) + +set(JLINK_DEVICE ATSAMD51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD51J19A__ + ) +endfunction() diff --git a/hw/bsp/samd5x_e5x/boards/pyportal/board.h b/hw/bsp/samd5x_e5x/boards/pyportal/board.h new file mode 100644 index 000000000..ff04c900b --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/pyportal/board.h @@ -0,0 +1,50 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PIN (32+23) +#define LED_STATE_ON 1 + +// Button +#define BUTTON_PIN (32+22) // D2 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_TX_PIN (32 + 13) +#define UART_RX_PIN (32 + 12) + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd5x_e5x/boards/pyportal/board.mk b/hw/bsp/samd5x_e5x/boards/pyportal/board.mk new file mode 100644 index 000000000..811c5f4e3 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/pyportal/board.mk @@ -0,0 +1,10 @@ +SAM_FAMILY = samd51 + +CFLAGS += -D__SAMD51J19A__ + +LD_FILE = $(BOARD_PATH)/$(BOARD).ld + +# For flash-jlink target +JLINK_DEVICE = ATSAMD51J19 + +flash: flash-bossac diff --git a/hw/bsp/samd5x_e5x/boards/pyportal/pyportal.ld b/hw/bsp/samd5x_e5x/boards/pyportal/pyportal.ld new file mode 100644 index 000000000..1408c3018 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/pyportal/pyportal.ld @@ -0,0 +1,166 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAMD51G19A + * + * Copyright (c) 2017 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 + bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 + qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; + +ENTRY(Reset_Handler) + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + .bkupram (NOLOAD): + { + . = ALIGN(8); + _sbkupram = .; + *(.bkupram .bkupram.*); + . = ALIGN(8); + _ebkupram = .; + } > bkupram + + .qspi (NOLOAD): + { + . = ALIGN(8); + _sqspi = .; + *(.qspi .qspi.*); + . = ALIGN(8); + _eqspi = .; + } > qspi + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + end = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; +} diff --git a/hw/bsp/samd5x_e5x/boards/same54_xplained/board.cmake b/hw/bsp/samd5x_e5x/boards/same54_xplained/board.cmake new file mode 100644 index 000000000..4d98205bc --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/same54_xplained/board.cmake @@ -0,0 +1,10 @@ +set(SAM_FAMILY same54) + +set(JLINK_DEVICE ATSAME54P20) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/same54p20a_flash.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAME54P20A__ + ) +endfunction() diff --git a/hw/bsp/samd5x_e5x/boards/same54_xplained/board.h b/hw/bsp/samd5x_e5x/boards/same54_xplained/board.h new file mode 100644 index 000000000..faaa52b8e --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/same54_xplained/board.h @@ -0,0 +1,50 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PIN PIN_PC18 +#define LED_STATE_ON 1 + +// Button: D5 +#define BUTTON_PIN PIN_PB31 +#define BUTTON_STATE_ACTIVE 0 + +// UART: SERCOM2 +//#define UART_TX_PIN 23 +//#define UART_RX_PIN 22 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd5x_e5x/boards/same54_xplained/board.mk b/hw/bsp/samd5x_e5x/boards/same54_xplained/board.mk new file mode 100644 index 000000000..d10e9e34c --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/same54_xplained/board.mk @@ -0,0 +1,9 @@ +SAM_FAMILY = same54 + +CFLAGS += -D__SAME54P20A__ + +# All source paths should be relative to the top level. +LD_FILE = $(BOARD_PATH)/same54p20a_flash.ld + +# For flash-jlink target +JLINK_DEVICE = ATSAME54P20 diff --git a/hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_flash.ld b/hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_flash.ld new file mode 100644 index 000000000..8a9fd7d9f --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_flash.ld @@ -0,0 +1,166 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAME54P20A + * + * Copyright (c) 2019 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000 + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 + bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 + qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x10000; + +ENTRY(Reset_Handler) + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + .bkupram (NOLOAD): + { + . = ALIGN(8); + _sbkupram = .; + *(.bkupram .bkupram.*); + . = ALIGN(8); + _ebkupram = .; + } > bkupram + + .qspi (NOLOAD): + { + . = ALIGN(8); + _sqspi = .; + *(.qspi .qspi.*); + . = ALIGN(8); + _eqspi = .; + } > qspi + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; + end = .; +} diff --git a/hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_sram.ld b/hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_sram.ld new file mode 100644 index 000000000..c88617729 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_sram.ld @@ -0,0 +1,165 @@ +/** + * \file + * + * \brief Linker script for running in internal SRAM on the SAME54P20A + * + * Copyright (c) 2019 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 + bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 + qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x10000; + +ENTRY(Reset_Handler) + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > ram + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > ram + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + .bkupram (NOLOAD): + { + . = ALIGN(8); + _sbkupram = .; + *(.bkupram .bkupram.*); + . = ALIGN(8); + _ebkupram = .; + } > bkupram + + .qspi (NOLOAD): + { + . = ALIGN(8); + _sqspi = .; + *(.qspi .qspi.*); + . = ALIGN(8); + _eqspi = .; + } > qspi + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; + end = .; +} diff --git a/hw/bsp/samd5x_e5x/family.c b/hw/bsp/samd5x_e5x/family.c new file mode 100644 index 000000000..abaee353b --- /dev/null +++ b/hw/bsp/samd5x_e5x/family.c @@ -0,0 +1,448 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "sam.h" +#include "bsp/board_api.h" +#include "board.h" + +// Suppress warning caused by mcu driver +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif + +#include "hal_gpio.h" +#include "hal_init.h" +#include "hpl/gclk/hpl_gclk_base.h" +#include "hpl_mclk_config.h" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +/* Referenced GCLKs, should be initialized firstly */ +#define _GCLK_INIT_1ST 0xFFFFFFFF + +/* Not referenced GCLKs, initialized last */ +#define _GCLK_INIT_LAST (~_GCLK_INIT_1ST) + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_0_Handler(void) { + tud_int_handler(0); +} + +void USB_1_Handler(void) { + tud_int_handler(0); +} + +void USB_2_Handler(void) { + tud_int_handler(0); +} + +void USB_3_Handler(void) { + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// Implementation +//--------------------------------------------------------------------+ + +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 + +#define MAX3421_SERCOM TU_XSTRCAT(SERCOM, MAX3421_SERCOM_ID) +#define MAX3421_EIC_Handler TU_XSTRCAT3(EIC_, MAX3421_INTR_EIC_ID, _Handler) + +static void max3421_init(void); +#endif + +void board_init(void) { + // Clock init ( follow hpl_init.c ) + hri_nvmctrl_set_CTRLA_RWS_bf(NVMCTRL, 0); + + _osc32kctrl_init_sources(); + _oscctrl_init_sources(); + _mclk_init(); +#if _GCLK_INIT_1ST + _gclk_init_generators_by_fref(_GCLK_INIT_1ST); +#endif + _oscctrl_init_referenced_generators(); + _gclk_init_generators_by_fref(_GCLK_INIT_LAST); + + // Update SystemCoreClock since it is hard coded with asf4 and not correct + // Init 1ms tick timer (samd SystemCoreClock may not correct) + SystemCoreClock = CONF_CPU_FREQUENCY; + SysTick_Config(CONF_CPU_FREQUENCY / 1000); + + // Led init + gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_level(LED_PIN, 0); + +#ifdef BUTTON_PIN + // Button init + gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP); +#endif + +#if CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB_0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + NVIC_SetPriority(USB_1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + NVIC_SetPriority(USB_2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + NVIC_SetPriority(USB_3_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + + /* USB Clock init + * The USB module requires a GCLK_USB of 48 MHz ~ 0.25% clock + * for low speed and full speed operation. */ + hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN); + hri_mclk_set_AHBMASK_USB_bit(MCLK); + hri_mclk_set_APBBMASK_USB_bit(MCLK); + + // USB Pin Init + gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT); + gpio_set_pin_level(PIN_PA24, false); + gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF); + gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT); + gpio_set_pin_level(PIN_PA25, false); + gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF); + + gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM); + gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP); + +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 + max3421_init(); +#endif +} + +void board_init_after_tusb(void) { +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { + gpio_set_pin_level(LED_PIN, state); +} + +uint32_t board_button_read(void) { + // button is active low + #ifdef BUTTON_PIN + return gpio_get_pin_level(BUTTON_PIN) ? 0 : 1; + #else + return 0; + #endif +} + +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + + uint32_t did_addr[4] = {0x008061FC, 0x00806010, 0x00806014, 0x00806018}; + + for (int i = 0; i < 4; i++) { + uint32_t did = *((uint32_t const*) did_addr[i]); + did = TU_BSWAP32(did); // swap endian to match samd51 uf2 bootloader + memcpy(id + i * 4, &did, 4); + } + + return 16; +} + +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const* buf, int len) { + (void) buf; + (void) len; + return 0; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; +} + +uint32_t board_millis(void) { + return system_ticks; +} + +#if 0 +/* Initialize SERCOM2 for 115200 bps 8N1 using a 48 MHz clock */ +static inline void uart_init(void) { + gpio_set_pin_function(PIN_PB24, PINMUX_PB24D_SERCOM2_PAD1); + gpio_set_pin_function(PIN_PB25, PINMUX_PB25D_SERCOM2_PAD0); + + MCLK->APBBMASK.bit.SERCOM2_ = 1; + GCLK->PCHCTRL[SERCOM2_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN; + + BOARD_SERCOM->USART.CTRLA.bit.SWRST = 1; /* reset and disable SERCOM -> enable configuration */ + while (BOARD_SERCOM->USART.SYNCBUSY.bit.SWRST); + + BOARD_SERCOM->USART.CTRLA.reg = + SERCOM_USART_CTRLA_SAMPR(0) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ + SERCOM_USART_CTRLA_SAMPA(0) | /* 16x over sampling */ + SERCOM_USART_CTRLA_FORM(0) | /* 0x0 USART frame, 0x1 USART frame with parity, ... */ + SERCOM_USART_CTRLA_DORD | /* LSB first */ + SERCOM_USART_CTRLA_MODE(1) | /* 0x0 USART with external clock, 0x1 USART with internal clock */ + SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ + SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ + + BOARD_SERCOM->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ + SERCOM_USART_CTRLB_TXEN | /* transmitter enabled */ + SERCOM_USART_CTRLB_RXEN; /* receiver enabled */ + // BOARD_SERCOM->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(0) | SERCOM_USART_BAUD_FRAC_BAUD(26); /* 48000000/(16*115200) = 26.041666667 */ + BOARD_SERCOM->USART.BAUD.reg = SERCOM_USART_BAUD_BAUD(63019); /* 65536*(1−16*115200/48000000) */ + + BOARD_SERCOM->USART.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ + while (BOARD_SERCOM->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ +} + +static inline void uart_send_buffer(uint8_t const* text, size_t len) { + for (size_t i = 0; i < len; ++i) { + BOARD_SERCOM->USART.DATA.reg = text[i]; + while ((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); + } +} + +static inline void uart_send_str(const char* text) { + while (*text) { + BOARD_SERCOM->USART.DATA.reg = *text++; + while ((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); + } +} + +#endif + +#endif + +//--------------------------------------------------------------------+ +// API: SPI transfer with MAX3421E, must be implemented by application +//--------------------------------------------------------------------+ +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 + +static void max3421_init(void) { + //------------- SPI Init -------------// + + // MAX3421E max SPI clock is 26MHz however SAMD can only work reliably at 12 Mhz + uint32_t const baudrate = 12000000u; + + struct { + volatile uint32_t* mck_apb; + uint32_t mask; + uint8_t gclk_id_core; + uint8_t gclk_id_slow; + } const sercom_clock[] = { + { &MCLK->APBAMASK.reg, MCLK_APBAMASK_SERCOM0, SERCOM0_GCLK_ID_CORE, SERCOM0_GCLK_ID_SLOW }, + { &MCLK->APBAMASK.reg, MCLK_APBAMASK_SERCOM1, SERCOM1_GCLK_ID_CORE, SERCOM1_GCLK_ID_SLOW }, + { &MCLK->APBBMASK.reg, MCLK_APBBMASK_SERCOM2, SERCOM2_GCLK_ID_CORE, SERCOM2_GCLK_ID_SLOW }, + { &MCLK->APBBMASK.reg, MCLK_APBBMASK_SERCOM3, SERCOM3_GCLK_ID_CORE, SERCOM3_GCLK_ID_SLOW }, + { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM4, SERCOM4_GCLK_ID_CORE, SERCOM4_GCLK_ID_SLOW }, + { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM5, SERCOM5_GCLK_ID_CORE, SERCOM5_GCLK_ID_SLOW }, + #ifdef SERCOM6_GCLK_ID_CORE + { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM6, SERCOM6_GCLK_ID_CORE, SERCOM6_GCLK_ID_SLOW }, + #endif + #ifdef SERCOM7_GCLK_ID_CORE + { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM7, SERCOM7_GCLK_ID_CORE, SERCOM7_GCLK_ID_SLOW }, + #endif + }; + + Sercom* sercom = MAX3421_SERCOM; + + // Enable the APB clock for SERCOM + *sercom_clock[MAX3421_SERCOM_ID].mck_apb |= sercom_clock[MAX3421_SERCOM_ID].mask; + + // Configure GCLK for SERCOM + GCLK->PCHCTRL[sercom_clock[MAX3421_SERCOM_ID].gclk_id_core].reg = + GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + GCLK->PCHCTRL[sercom_clock[MAX3421_SERCOM_ID].gclk_id_slow].reg = + GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + + // Disable the SPI module + sercom->SPI.CTRLA.bit.ENABLE = 0; + + // Reset the SPI module + sercom->SPI.CTRLA.bit.SWRST = 1; + while (sercom->SPI.SYNCBUSY.bit.SWRST); + + // Set up SPI in master mode, MSB first, SPI mode 0 + sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_DOPO(MAX3421_TX_PAD) | SERCOM_SPI_CTRLA_DIPO(MAX3421_RX_PAD) | + SERCOM_SPI_CTRLA_MODE(3); + + sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(0) | SERCOM_SPI_CTRLB_RXEN; + while (sercom->SPI.SYNCBUSY.bit.CTRLB == 1); + + // Set the baud rate + uint8_t baud_reg = (uint8_t) (SystemCoreClock / (2 * baudrate)); + if (baud_reg) { + baud_reg--; + } + + sercom->SPI.BAUD.reg = baud_reg; + + // Configure PA12 as MOSI (PAD0), PA13 as SCK (PAD1), PA14 as MISO (PAD2), function C (sercom) + gpio_set_pin_direction(MAX3421_SCK_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_pull_mode(MAX3421_SCK_PIN, GPIO_PULL_OFF); + gpio_set_pin_function(MAX3421_SCK_PIN, MAX3421_SERCOM_FUNCTION); + + gpio_set_pin_direction(MAX3421_MOSI_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_pull_mode(MAX3421_MOSI_PIN, GPIO_PULL_OFF); + gpio_set_pin_function(MAX3421_MOSI_PIN, MAX3421_SERCOM_FUNCTION); + + gpio_set_pin_direction(MAX3421_MISO_PIN, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(MAX3421_MISO_PIN, GPIO_PULL_OFF); + gpio_set_pin_function(MAX3421_MISO_PIN, MAX3421_SERCOM_FUNCTION); + + // CS pin + gpio_set_pin_direction(MAX3421_CS_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_level(MAX3421_CS_PIN, 1); + + // Enable the SPI module + sercom->SPI.CTRLA.bit.ENABLE = 1; + while (sercom->SPI.SYNCBUSY.bit.ENABLE) {} + + //------------- External Interrupt -------------// + + // Enable the APB clock for EIC (External Interrupt Controller) + MCLK->APBAMASK.reg |= MCLK_APBAMASK_EIC; + + // Configure GCLK for EIC + GCLK->PCHCTRL[EIC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + + // Configure PA20 as an input with function A (external interrupt) + gpio_set_pin_direction(MAX3421_INTR_PIN, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(MAX3421_INTR_PIN, GPIO_PULL_UP); + gpio_set_pin_function(MAX3421_INTR_PIN, 0); + + // Disable EIC + EIC->CTRLA.bit.ENABLE = 0; + while (EIC->SYNCBUSY.bit.ENABLE); + + // Configure EIC to trigger on falling edge + volatile uint32_t* eic_config; + uint8_t sense_shift; + if (MAX3421_INTR_EIC_ID < 8) { + eic_config = &EIC->CONFIG[0].reg; + sense_shift = MAX3421_INTR_EIC_ID * 4; + } else { + eic_config = &EIC->CONFIG[1].reg; + sense_shift = (MAX3421_INTR_EIC_ID - 8) * 4; + } + + *eic_config &= ~(7 << sense_shift); + *eic_config |= 2 << sense_shift; + +#if CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(EIC_0_IRQn + MAX3421_INTR_EIC_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + + // Enable External Interrupt + EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << MAX3421_INTR_EIC_ID); + + // Enable EIC + EIC->CTRLA.bit.ENABLE = 1; + while (EIC->SYNCBUSY.bit.ENABLE); +} + +void MAX3421_EIC_Handler(void) { + // Clear the interrupt flag + EIC->INTFLAG.reg = EIC_INTFLAG_EXTINT(1 << MAX3421_INTR_EIC_ID); + + // Call the TinyUSB interrupt handler + tuh_int_handler(1, true); +} + +// API to enable/disable MAX3421 INTR pin interrupt +void tuh_max3421_int_api(uint8_t rhport, bool enabled) { + (void) rhport; + + const IRQn_Type irq = EIC_0_IRQn + MAX3421_INTR_EIC_ID; + if (enabled) { + NVIC_EnableIRQ(irq); + } else { + NVIC_DisableIRQ(irq); + } +} + +// API to control MAX3421 SPI CS +void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { + (void) rhport; + gpio_set_pin_level(MAX3421_CS_PIN, active ? 0 : 1); +} + +// API to transfer data with MAX3421 SPI +// Either tx_buf or rx_buf can be NULL, which means transfer is write or read only +bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { + (void) rhport; + + Sercom* sercom = MAX3421_SERCOM; + + for (size_t count = 0; count < xfer_bytes; count++) { + // Wait for the transmit buffer to be empty + while (!sercom->SPI.INTFLAG.bit.DRE); + + // Write data to be transmitted + uint8_t data = 0x00; + if (tx_buf) { + data = tx_buf[count]; + } + + sercom->SPI.DATA.reg = (uint32_t) data; + + // Wait for the receive buffer to be filled + while (!sercom->SPI.INTFLAG.bit.RXC); + + // Read received data + data = (uint8_t) sercom->SPI.DATA.reg; + if (rx_buf) { + rx_buf[count] = data; + } + } + + // wait for bus idle and clear flags + while (!(sercom->SPI.INTFLAG.reg & (SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE))); + sercom->SPI.INTFLAG.reg = SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE; + + return true; +} + +#endif + +void HardFault_Handler(void) { + __BKPT(0); + while (1); +} diff --git a/hw/bsp/samd5x_e5x/family.cmake b/hw/bsp/samd5x_e5x/family.cmake new file mode 100644 index 000000000..6d64a5fe4 --- /dev/null +++ b/hw/bsp/samd5x_e5x/family.cmake @@ -0,0 +1,109 @@ +include_guard() + +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +set(SDK_DIR ${TOP}/hw/mcu/microchip/${SAM_FAMILY}) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS SAMD51 SAME54 CACHE INTERNAL "") +set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -c \"set CHIPNAME samd51\" -f target/atsame5x.cfg") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + set(LD_FILE_Clang ${LD_FILE_GNU}) + if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) + message(FATAL_ERROR "LD_FILE_${CMAKE_C_COMPILER_ID} not defined") + endif () + + set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_${SAM_FAMILY}.c) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/gcc/system_${SAM_FAMILY}.c + ${SDK_DIR}/hal/src/hal_atomic.c + ${SDK_DIR}/hpl/gclk/hpl_gclk.c + ${SDK_DIR}/hpl/mclk/hpl_mclk.c + ${SDK_DIR}/hpl/osc32kctrl/hpl_osc32kctrl.c + ${SDK_DIR}/hpl/oscctrl/hpl_oscctrl.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR} + ${SDK_DIR}/config + ${SDK_DIR}/include + ${SDK_DIR}/hal/include + ${SDK_DIR}/hal/utils/include + ${SDK_DIR}/hpl/port + ${SDK_DIR}/hri + ${CMSIS_5}/CMSIS/Core/Include + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_SAMD51 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/microchip/samd/dcd_samd.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_jlink(${TARGET}) + #family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) +endfunction() diff --git a/hw/bsp/samd5x_e5x/family.mk b/hw/bsp/samd5x_e5x/family.mk new file mode 100644 index 000000000..9b1a23db4 --- /dev/null +++ b/hw/bsp/samd5x_e5x/family.mk @@ -0,0 +1,51 @@ +UF2_FAMILY_ID = 0x55114460 + +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= cortex-m4 + +SDK_DIR = hw/mcu/microchip/${SAM_FAMILY} + +CFLAGS += \ + -flto \ + -DCFG_TUSB_MCU=OPT_MCU_SAMD51 + +# SAM driver is flooded with -Wcast-qual which slow down complication significantly +CFLAGS_SKIP += -Wcast-qual + +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs + +SRC_C += \ + src/portable/microchip/samd/dcd_samd.c \ + ${SDK_DIR}/gcc/gcc/startup_${SAM_FAMILY}.c \ + ${SDK_DIR}/gcc/system_${SAM_FAMILY}.c \ + ${SDK_DIR}/hpl/gclk/hpl_gclk.c \ + ${SDK_DIR}/hpl/mclk/hpl_mclk.c \ + ${SDK_DIR}/hpl/osc32kctrl/hpl_osc32kctrl.c \ + ${SDK_DIR}/hpl/oscctrl/hpl_oscctrl.c \ + ${SDK_DIR}/hal/src/hal_atomic.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/${SDK_DIR} \ + $(TOP)/${SDK_DIR}/config \ + $(TOP)/${SDK_DIR}/include \ + $(TOP)/${SDK_DIR}/hal/include \ + $(TOP)/${SDK_DIR}/hal/utils/include \ + $(TOP)/${SDK_DIR}/hpl/port \ + $(TOP)/${SDK_DIR}/hri \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + +# flash using bossac at least version 1.8 +# can be found in arduino15/packages/arduino/tools/bossac/ +# Add it to your PATH or change BOSSAC variable to match your installation +BOSSAC = bossac + +flash-bossac: $(BUILD)/$(PROJECT).bin + @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) + $(BOSSAC) --port=$(SERIAL) -U -i --offset=0x4000 -e -w $^ -R + +# flash using edbg from https://github.com/ataradov/edbg +flash-edbg: $(BUILD)/$(PROJECT).bin + edbg --verbose -t $(MCU) -pv -f $< -- cgit v1.3.1 From 704412bb481c285dded617aacb29c7346baf6bf4 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 16:15:29 +0700 Subject: add cmake for tm4c --- .github/workflows/build_arm.yml | 3 +- .github/workflows/build_cmake.yml | 3 +- hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h | 149 +++++++++++++++++++++ hw/bsp/tm4c/boards/ek_tm4c123gxl/board.cmake | 12 ++ hw/bsp/tm4c/boards/ek_tm4c123gxl/board.h | 52 ++++++++ hw/bsp/tm4c/boards/ek_tm4c123gxl/board.mk | 13 ++ hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld | 66 +++++++++ hw/bsp/tm4c/family.c | 177 +++++++++++++++++++++++++ hw/bsp/tm4c/family.cmake | 95 +++++++++++++ hw/bsp/tm4c/family.mk | 28 ++++ hw/bsp/tm4c123/boards/ek_tm4c123gxl/board.h | 52 -------- hw/bsp/tm4c123/boards/ek_tm4c123gxl/board.mk | 11 -- hw/bsp/tm4c123/boards/ek_tm4c123gxl/tm4c123.ld | 65 --------- hw/bsp/tm4c123/family.c | 177 ------------------------- hw/bsp/tm4c123/family.mk | 30 ----- tools/get_deps.py | 7 +- 16 files changed, 599 insertions(+), 341 deletions(-) create mode 100644 hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/tm4c/boards/ek_tm4c123gxl/board.cmake create mode 100644 hw/bsp/tm4c/boards/ek_tm4c123gxl/board.h create mode 100644 hw/bsp/tm4c/boards/ek_tm4c123gxl/board.mk create mode 100644 hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld create mode 100644 hw/bsp/tm4c/family.c create mode 100644 hw/bsp/tm4c/family.cmake create mode 100644 hw/bsp/tm4c/family.mk delete mode 100644 hw/bsp/tm4c123/boards/ek_tm4c123gxl/board.h delete mode 100644 hw/bsp/tm4c123/boards/ek_tm4c123gxl/board.mk delete mode 100644 hw/bsp/tm4c123/boards/ek_tm4c123gxl/tm4c123.ld delete mode 100644 hw/bsp/tm4c123/family.c delete mode 100644 hw/bsp/tm4c123/family.mk diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 40dc77593..15f12550f 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -36,8 +36,7 @@ jobs: family: # Alphabetical order - 'mm32' - - 'same5x' - - 'tm4c123 xmc4000' + - 'xmc4000' steps: - name: Setup Python uses: actions/setup-python@v5 diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 75ce707aa..3fb277d00 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -48,7 +48,7 @@ jobs: - 'nrf' - 'ra' - 'rp2040' - - 'samd11 samd21 saml2x samd51' + - 'samd11 samd21 saml2x samd5x_e5x' - 'stm32f0' - 'stm32f1' - 'stm32f2' @@ -62,6 +62,7 @@ jobs: - 'stm32l4' - 'stm32u5' - 'stm32wb' + - 'tm4c' steps: - name: Setup Python uses: actions/setup-python@v5 diff --git a/hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..3dd5a1ee1 --- /dev/null +++ b/hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "msp.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 3 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<FLASH + + .data : AT(ADDR(.text) + SIZEOF(.text)) + { + . = ALIGN(4); + __start_data = . ; + __la_data = LOADADDR(.data); + *(.data) + *(.data.*) + . = ALIGN(4); + __end_data = . ; + + } >SRAM + + .bss : + { + . = ALIGN(4) ; + __start_bss = . ; + __bss_start__ = __start_bss; + *(.bss) + *(.bss.*) + *(.COMMON) + __end_bss = . ; + . = ALIGN(4); + }>SRAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >SRAM +} diff --git a/hw/bsp/tm4c/family.c b/hw/bsp/tm4c/family.c new file mode 100644 index 000000000..738bc3fa0 --- /dev/null +++ b/hw/bsp/tm4c/family.c @@ -0,0 +1,177 @@ +#include "TM4C123.h" +#include "bsp/board_api.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB0_Handler(void) +{ +#if CFG_TUH_ENABLED + tuh_int_handler(0, true); +#endif + +#if CFG_TUD_ENABLED + tud_int_handler(0); +#endif +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +static void board_uart_init (void) +{ + SYSCTL->RCGCUART |= (1 << 0); // Enable the clock to UART0 + SYSCTL->RCGCGPIO |= (1 << 0); // Enable the clock to GPIOA + + GPIOA->AFSEL |= (1 << 1) | (1 << 0); // Enable the alternate function on pin PA0 & PA1 + GPIOA->PCTL |= (1 << 0) | (1 << 4); // Configure the GPIOPCTL register to select UART0 in PA0 and PA1 + GPIOA->DEN |= (1 << 0) | (1 << 1); // Enable the digital functionality in PA0 and PA1 + + // BAUDRATE = 115200, with SystemCoreClock = 50 Mhz refer manual for calculation + // - BRDI = SystemCoreClock / (16* baud) + // - BRDF = int(fraction*64 + 0.5) + UART0->CTL &= ~(1 << 0); // Disable UART0 by clearing UARTEN bit in the UARTCTL register + UART0->IBRD = 27; // Write the integer portion of the BRD to the UARTIRD register + UART0->FBRD = 8; // Write the fractional portion of the BRD to the UARTFBRD registerer + + UART0->LCRH = (0x3 << 5); // 8-bit, no parity, 1 stop bit + UART0->CC = 0x0; // Configure the UART clock source as system clock + + UART0->CTL = (1 << 0) | (1 << 8) | (1 << 9); // UART0 Enable, Transmit Enable, Receive Enable +} + +static void initialize_board_led (GPIOA_Type *port, uint8_t PinMsk, uint8_t dirmsk) +{ + /* Enable PortF Clock */ + SYSCTL->RCGCGPIO |= (1 << 5); + + /* Let the clock stabilize */ + while ( !((SYSCTL->PRGPIO) & (1 << 5)) ) {} + + /* Port Digital Enable */ + port->DEN |= PinMsk; + + /* Set direction */ + port->DIR = dirmsk; +} + +static void board_switch_init (void) +{ + GPIOF->DIR &= ~(1 << BOARD_BTN); + GPIOF->PUR |= (1 << BOARD_BTN); + GPIOF->DEN |= (1 << BOARD_BTN); +} + +static void WriteGPIOPin (GPIOA_Type *port, uint8_t PinMsk, bool state) +{ + if ( state ) + { + port->DATA |= PinMsk; + } + else + { + port->DATA &= ~(PinMsk); + } +} + +static uint32_t ReadGPIOPin (GPIOA_Type *port, uint8_t pinMsk) +{ + return (port->DATA & pinMsk); +} + +void board_init (void) +{ + SystemCoreClockUpdate(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + /* Reset USB */ + SYSCTL->SRCR2 |= (1u << 16); + + for ( volatile uint8_t i = 0; i < 20; i++ ) {} + + SYSCTL->SRCR2 &= ~(1u << 16); + + /* Open the USB clock gate */ + SYSCTL->RCGCUSB |= (1 << 0); + + /* Power-up USB PLL */ + SYSCTL->RCC2 &= ~(1u << 14); + + /* USB IO Initialization */ + SYSCTL->RCGCGPIO |= (1u << 3); + + /* Let the clock stabilize */ + while ( !(SYSCTL->PRGPIO & (1u << 3)) ) {} + + /* USB IOs to Analog Mode */ + GPIOD->AFSEL &= ~((1u << 4) | (1u << 5)); + GPIOD->DEN &= ~((1u << 4) | (1u << 5)); + GPIOD->AMSEL |= ((1u << 4) | (1u << 5)); + + uint8_t leds = (1 << LED_PIN_RED) | (1 << LED_PIN_BLUE) | (1 << LED_PIN_GREEN); + uint8_t dirmsk = (1 << LED_PIN_RED) | (1 << LED_PIN_BLUE) | (1 << LED_PIN_GREEN); + + /* Configure GPIO for board LED */ + initialize_board_led(LED_PORT, leds, dirmsk); + + /* Configure GPIO for board switch */ + board_switch_init(); + + /* Initialize board UART */ + board_uart_init(); + + TU_LOG1_INT(SystemCoreClock); +} + +void board_led_write (bool state) +{ + WriteGPIOPin(LED_PORT, (1 << LED_PIN_BLUE), state); +} + +uint32_t board_button_read (void) +{ + uint32_t gpio_value = ReadGPIOPin(BOARD_BTN_PORT, BOARD_BTN_Msk); + return BUTTON_STATE_ACTIVE ? gpio_value : !gpio_value; +} + +int board_uart_write (void const *buf, int len) +{ + uint8_t const * data = buf; + + for ( int i = 0; i < len; i++ ) + { + while ( (UART0->FR & (1 << 5)) != 0 ) {} // Poll until previous data was shofted out + UART0->DR = data[i]; // Write UART0 DATA REGISTER + } + + return len; +} + +int board_uart_read (uint8_t *buf, int len) +{ + (void) buf; + (void) len; + return 0; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler (void) +{ + system_ticks++; +} + +uint32_t board_millis (void) +{ + return system_ticks; +} +#endif diff --git a/hw/bsp/tm4c/family.cmake b/hw/bsp/tm4c/family.cmake new file mode 100644 index 000000000..f7ab2fb28 --- /dev/null +++ b/hw/bsp/tm4c/family.cmake @@ -0,0 +1,95 @@ +include_guard() + +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +set(MCU_VARIANT tm4c${MCU_SUB_VARIANT}) +set(MCU_VARIANT_UPPER TM4C${MCU_SUB_VARIANT}) + +set(SDK_DIR ${TOP}/hw/mcu/ti/${MCU_VARIANT}xx) +set(CMSIS_DIR ${TOP}/lib/CMSIS_5) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS TM4C123 CACHE INTERNAL "") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + set(LD_FILE_Clang ${LD_FILE_GNU}) + + set(STARTUP_FILE_GNU ${SDK_DIR}/Source/GCC/${MCU_VARIANT}_startup.c) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/Source/system_${MCU_VARIANT_UPPER}.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/Include/${MCU_VARIANT_UPPER} + ${CMSIS_DIR}/CMSIS/Core/Include + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + --specs=nosys.specs --specs=nano.specs + -uvectors + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for MSP432E4") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_TM4C123 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/mentor/musb/dcd_musb.c + ${TOP}/src/portable/mentor/musb/hcd_musb.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) +endfunction() diff --git a/hw/bsp/tm4c/family.mk b/hw/bsp/tm4c/family.mk new file mode 100644 index 000000000..76ae785b2 --- /dev/null +++ b/hw/bsp/tm4c/family.mk @@ -0,0 +1,28 @@ +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= cortex-m4 + +MCU_VARIANT = tm4c${MCU_SUB_VARIANT} +MCU_VARIANT_UPPER = TM4C${MCU_SUB_VARIANT} + +SDK_DIR = hw/mcu/ti/${MCU_VARIANT}xx + +CFLAGS += \ + -flto \ + -DCFG_TUSB_MCU=OPT_MCU_TM4C123 \ + -uvectors \ + +# mcu driver cause following warnings +CFLAGS += -Wno-error=strict-prototypes -Wno-error=cast-qual + +LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs + +INC += \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(SDK_DIR)/Include/${MCU_VARIANT_UPPER} \ + $(TOP)/$(BOARD_PATH) + +SRC_C += \ + src/portable/mentor/musb/dcd_musb.c \ + src/portable/mentor/musb/hcd_musb.c \ + $(SDK_DIR)/Source/system_${MCU_VARIANT_UPPER}.c \ + $(SDK_DIR)/Source/GCC/${MCU_VARIANT}_startup.c diff --git a/hw/bsp/tm4c123/boards/ek_tm4c123gxl/board.h b/hw/bsp/tm4c123/boards/ek_tm4c123gxl/board.h deleted file mode 100644 index 5732056ae..000000000 --- a/hw/bsp/tm4c123/boards/ek_tm4c123gxl/board.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2021, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef _BOARD_H_ -#define _BOARD_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#define BOARD_UART UART0 -#define BOARD_UART_PORT GPIOA - -#define BOARD_BTN_PORT GPIOF -#define BOARD_BTN 4 -#define BOARD_BTN_Msk (1u<<4) -#define BUTTON_STATE_ACTIVE 0 - -#define LED_PORT GPIOF -#define LED_PIN_RED 1 -#define LED_PIN_BLUE 2 -#define LED_PIN_GREEN 3 -#define LED_STATE_ON 1 - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/hw/bsp/tm4c123/boards/ek_tm4c123gxl/board.mk b/hw/bsp/tm4c123/boards/ek_tm4c123gxl/board.mk deleted file mode 100644 index 0ff24ab60..000000000 --- a/hw/bsp/tm4c123/boards/ek_tm4c123gxl/board.mk +++ /dev/null @@ -1,11 +0,0 @@ -CFLAGS += -DTM4C123GH6PM - -LD_FILE = $(BOARD_PATH)/tm4c123.ld - -# For flash-jlink target -JLINK_DEVICE = TM4C123GH6PM - -# flash using openocd -OPENOCD_OPTION = -f board/ti_ek-tm4c123gxl.cfg - -flash: flash-openocd diff --git a/hw/bsp/tm4c123/boards/ek_tm4c123gxl/tm4c123.ld b/hw/bsp/tm4c123/boards/ek_tm4c123gxl/tm4c123.ld deleted file mode 100644 index 351857bd6..000000000 --- a/hw/bsp/tm4c123/boards/ek_tm4c123gxl/tm4c123.ld +++ /dev/null @@ -1,65 +0,0 @@ -ENTRY(Reset_Handler) - -_estack = 0x20008000; /* end of RAM */ -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0; /* required amount of heap */ -_Min_Stack_Size = 0x1000; /* required amount of stack */ - - -MEMORY -{ - FLASH(rx) : ORIGIN = 0x00000000, LENGTH = 256K - SRAM(rwx) : ORIGIN = 0x20000000, LENGTH = 32K -} - -SECTIONS -{ - .text : - { - . = ALIGN(4) ; - *(.vectors) - *(.text) - *(.text.*) - *(.init) - *(.fini) - *(.rodata) - *(.rodata.*) - . = ALIGN(4) ; - __end_text = . ; - } >FLASH - - .data : AT(ADDR(.text) + SIZEOF(.text)) - { - . = ALIGN(4); - __start_data = . ; - __la_data = LOADADDR(.data); - *(.data) - *(.data.*) - . = ALIGN(4); - __end_data = . ; - - } >SRAM - - .bss : - { - . = ALIGN(4) ; - __start_bss = . ; - __bss_start__ = __start_bss; - *(.bss) - *(.bss.*) - *(.COMMON) - __end_bss = . ; - . = ALIGN(4); - }>SRAM - - /* User_heap_stack section, used to check that there is enough RAM left */ - ._user_heap_stack : - { - . = ALIGN(8); - PROVIDE ( end = . ); - PROVIDE ( _end = . ); - . = . + _Min_Heap_Size; - . = . + _Min_Stack_Size; - . = ALIGN(8); - } >SRAM -} diff --git a/hw/bsp/tm4c123/family.c b/hw/bsp/tm4c123/family.c deleted file mode 100644 index 738bc3fa0..000000000 --- a/hw/bsp/tm4c123/family.c +++ /dev/null @@ -1,177 +0,0 @@ -#include "TM4C123.h" -#include "bsp/board_api.h" -#include "board.h" - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB0_Handler(void) -{ -#if CFG_TUH_ENABLED - tuh_int_handler(0, true); -#endif - -#if CFG_TUD_ENABLED - tud_int_handler(0); -#endif -} - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM -//--------------------------------------------------------------------+ - -static void board_uart_init (void) -{ - SYSCTL->RCGCUART |= (1 << 0); // Enable the clock to UART0 - SYSCTL->RCGCGPIO |= (1 << 0); // Enable the clock to GPIOA - - GPIOA->AFSEL |= (1 << 1) | (1 << 0); // Enable the alternate function on pin PA0 & PA1 - GPIOA->PCTL |= (1 << 0) | (1 << 4); // Configure the GPIOPCTL register to select UART0 in PA0 and PA1 - GPIOA->DEN |= (1 << 0) | (1 << 1); // Enable the digital functionality in PA0 and PA1 - - // BAUDRATE = 115200, with SystemCoreClock = 50 Mhz refer manual for calculation - // - BRDI = SystemCoreClock / (16* baud) - // - BRDF = int(fraction*64 + 0.5) - UART0->CTL &= ~(1 << 0); // Disable UART0 by clearing UARTEN bit in the UARTCTL register - UART0->IBRD = 27; // Write the integer portion of the BRD to the UARTIRD register - UART0->FBRD = 8; // Write the fractional portion of the BRD to the UARTFBRD registerer - - UART0->LCRH = (0x3 << 5); // 8-bit, no parity, 1 stop bit - UART0->CC = 0x0; // Configure the UART clock source as system clock - - UART0->CTL = (1 << 0) | (1 << 8) | (1 << 9); // UART0 Enable, Transmit Enable, Receive Enable -} - -static void initialize_board_led (GPIOA_Type *port, uint8_t PinMsk, uint8_t dirmsk) -{ - /* Enable PortF Clock */ - SYSCTL->RCGCGPIO |= (1 << 5); - - /* Let the clock stabilize */ - while ( !((SYSCTL->PRGPIO) & (1 << 5)) ) {} - - /* Port Digital Enable */ - port->DEN |= PinMsk; - - /* Set direction */ - port->DIR = dirmsk; -} - -static void board_switch_init (void) -{ - GPIOF->DIR &= ~(1 << BOARD_BTN); - GPIOF->PUR |= (1 << BOARD_BTN); - GPIOF->DEN |= (1 << BOARD_BTN); -} - -static void WriteGPIOPin (GPIOA_Type *port, uint8_t PinMsk, bool state) -{ - if ( state ) - { - port->DATA |= PinMsk; - } - else - { - port->DATA &= ~(PinMsk); - } -} - -static uint32_t ReadGPIOPin (GPIOA_Type *port, uint8_t pinMsk) -{ - return (port->DATA & pinMsk); -} - -void board_init (void) -{ - SystemCoreClockUpdate(); - -#if CFG_TUSB_OS == OPT_OS_NONE - // 1ms tick timer - SysTick_Config(SystemCoreClock / 1000); -#elif CFG_TUSB_OS == OPT_OS_FREERTOS - // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); -#endif - - /* Reset USB */ - SYSCTL->SRCR2 |= (1u << 16); - - for ( volatile uint8_t i = 0; i < 20; i++ ) {} - - SYSCTL->SRCR2 &= ~(1u << 16); - - /* Open the USB clock gate */ - SYSCTL->RCGCUSB |= (1 << 0); - - /* Power-up USB PLL */ - SYSCTL->RCC2 &= ~(1u << 14); - - /* USB IO Initialization */ - SYSCTL->RCGCGPIO |= (1u << 3); - - /* Let the clock stabilize */ - while ( !(SYSCTL->PRGPIO & (1u << 3)) ) {} - - /* USB IOs to Analog Mode */ - GPIOD->AFSEL &= ~((1u << 4) | (1u << 5)); - GPIOD->DEN &= ~((1u << 4) | (1u << 5)); - GPIOD->AMSEL |= ((1u << 4) | (1u << 5)); - - uint8_t leds = (1 << LED_PIN_RED) | (1 << LED_PIN_BLUE) | (1 << LED_PIN_GREEN); - uint8_t dirmsk = (1 << LED_PIN_RED) | (1 << LED_PIN_BLUE) | (1 << LED_PIN_GREEN); - - /* Configure GPIO for board LED */ - initialize_board_led(LED_PORT, leds, dirmsk); - - /* Configure GPIO for board switch */ - board_switch_init(); - - /* Initialize board UART */ - board_uart_init(); - - TU_LOG1_INT(SystemCoreClock); -} - -void board_led_write (bool state) -{ - WriteGPIOPin(LED_PORT, (1 << LED_PIN_BLUE), state); -} - -uint32_t board_button_read (void) -{ - uint32_t gpio_value = ReadGPIOPin(BOARD_BTN_PORT, BOARD_BTN_Msk); - return BUTTON_STATE_ACTIVE ? gpio_value : !gpio_value; -} - -int board_uart_write (void const *buf, int len) -{ - uint8_t const * data = buf; - - for ( int i = 0; i < len; i++ ) - { - while ( (UART0->FR & (1 << 5)) != 0 ) {} // Poll until previous data was shofted out - UART0->DR = data[i]; // Write UART0 DATA REGISTER - } - - return len; -} - -int board_uart_read (uint8_t *buf, int len) -{ - (void) buf; - (void) len; - return 0; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; -void SysTick_Handler (void) -{ - system_ticks++; -} - -uint32_t board_millis (void) -{ - return system_ticks; -} -#endif diff --git a/hw/bsp/tm4c123/family.mk b/hw/bsp/tm4c123/family.mk deleted file mode 100644 index 49e39f6a0..000000000 --- a/hw/bsp/tm4c123/family.mk +++ /dev/null @@ -1,30 +0,0 @@ -DEPS_SUBMODULES += hw/mcu/ti -MCU_DIR=hw/mcu/ti/tm4c123xx - -include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= cortex-m4 - -CFLAGS += \ - -flto \ - -DCFG_TUSB_MCU=OPT_MCU_TM4C123 \ - -uvectors \ - -DTM4C123GH6PM - -# mcu driver cause following warnings -CFLAGS += -Wno-error=strict-prototypes -Wno-error=cast-qual - -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs - -# All source paths should be relative to the top level. -LD_FILE = $(BOARD_PATH)/tm4c123.ld - -INC += \ - $(TOP)/$(MCU_DIR)/CMSIS/5.7.0/CMSIS/Include \ - $(TOP)/$(MCU_DIR)/Include/TM4C123 \ - $(TOP)/$(BOARD_PATH) - -SRC_C += \ - src/portable/mentor/musb/dcd_musb.c \ - src/portable/mentor/musb/hcd_musb.c \ - $(MCU_DIR)/Source/system_TM4C123.c \ - $(MCU_DIR)/Source/GCC/tm4c123_startup.c diff --git a/tools/get_deps.py b/tools/get_deps.py index bf6ef8c00..066f3e511 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -37,7 +37,7 @@ deps_optional = { 'xmc4000'], 'hw/mcu/microchip': ['https://github.com/hathach/microchip_driver.git', '9e8b37e307d8404033bb881623a113931e1edf27', - 'sam3x samd11 samd21 samd51 same5x same7x saml2x samg'], + 'sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg'], 'hw/mcu/mindmotion/mm32sdk': ['https://github.com/hathach/mm32sdk.git', '0b79559eb411149d36e073c1635c620e576308d4', 'mm32'], @@ -166,7 +166,7 @@ deps_optional = { 'stm32wb'], 'hw/mcu/ti': ['https://github.com/hathach/ti_driver.git', '143ed6cc20a7615d042b03b21e070197d473e6e5', - 'msp430 msp432e4 tm4c123'], + 'msp430 msp432e4 tm4c'], 'hw/mcu/wch/ch32v307': ['https://github.com/openwch/ch32v307.git', '17761f5cf9dbbf2dcf665b7c04934188add20082', 'ch32v307'], @@ -179,7 +179,8 @@ deps_optional = { 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43' 'stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5' 'stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wb' - 'sam3x samd11 samd21 samd51 same5x same7x saml2x samg'], + 'sam3x samd11 samd21 samd51 same5x same7x saml2x samg' + 'tm4c'], 'lib/sct_neopixel': ['https://github.com/gsteiert/sct_neopixel.git', 'e73e04ca63495672d955f9268e003cffe168fcd8', 'lpc55'], -- cgit v1.3.1 From f38fbbfb2b663cf0977417cf313345f56475cdad Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 16:48:55 +0700 Subject: add cmake for xmc4000 --- .github/workflows/build_arm.yml | 1 - .github/workflows/build_cmake.yml | 1 + hw/bsp/xmc4000/FreeRTOSConfig/FreeRTOSConfig.h | 149 ++++++++++++++++++++++++ hw/bsp/xmc4000/boards/xmc4500_relax/board.cmake | 10 ++ hw/bsp/xmc4000/boards/xmc4500_relax/board.mk | 2 +- hw/bsp/xmc4000/boards/xmc4700_relax/board.cmake | 10 ++ hw/bsp/xmc4000/boards/xmc4700_relax/board.mk | 2 +- hw/bsp/xmc4000/family.c | 41 +++---- hw/bsp/xmc4000/family.cmake | 97 +++++++++++++++ hw/bsp/xmc4000/family.mk | 28 +++-- 10 files changed, 303 insertions(+), 38 deletions(-) create mode 100644 hw/bsp/xmc4000/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/xmc4000/boards/xmc4500_relax/board.cmake create mode 100644 hw/bsp/xmc4000/boards/xmc4700_relax/board.cmake create mode 100644 hw/bsp/xmc4000/family.cmake diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 15f12550f..14c6d519c 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -36,7 +36,6 @@ jobs: family: # Alphabetical order - 'mm32' - - 'xmc4000' steps: - name: Setup Python uses: actions/setup-python@v5 diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 3fb277d00..a1409b22c 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -63,6 +63,7 @@ jobs: - 'stm32u5' - 'stm32wb' - 'tm4c' + - 'xmc4000' steps: - name: Setup Python uses: actions/setup-python@v5 diff --git a/hw/bsp/xmc4000/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/xmc4000/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..76eacea39 --- /dev/null +++ b/hw/bsp/xmc4000/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "xmc_device.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 6 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< Date: Fri, 3 May 2024 18:12:55 +0700 Subject: fix ci --- .github/workflows/build_cmake.yml | 4 ++-- hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index a1409b22c..f0937cc85 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -113,7 +113,7 @@ jobs: cmake-build/cmake-build-feather_nrf52840_express/*/*/*.elf - name: Upload Artifacts for Hardware Testing (samd51) - if: matrix.family == 'samd51' && github.repository_owner == 'hathach' + if: matrix.family == 'samd5x_e5x' && github.repository_owner == 'hathach' uses: actions/upload-artifact@v4 with: name: itsybitsy_m4 @@ -139,7 +139,7 @@ jobs: #- 'ra' port later #- 'rp2040' port later - 'samd21' - - 'samd51' + - 'samd5x_e5x' - 'stm32f0' - 'stm32f1' - 'stm32f2' diff --git a/hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h index 3dd5a1ee1..454b085e9 100644 --- a/hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h @@ -44,7 +44,7 @@ // skip if included from IAR assembler #ifndef __IASMARM__ - #include "msp.h" + #include "TM4C123.h" #endif /* Cortex M23/M33 port configuration. */ -- cgit v1.3.1 From 58248f3e7fd05374d9b4779afb4cb158be96874f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 23:15:14 +0700 Subject: mm32 temp --- hw/bsp/mm32/boards/mm32f327x_mb39/board.mk | 9 +++------ hw/bsp/mm32/family.mk | 3 --- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/hw/bsp/mm32/boards/mm32f327x_mb39/board.mk b/hw/bsp/mm32/boards/mm32f327x_mb39/board.mk index a0d92d1c7..803b3adff 100644 --- a/hw/bsp/mm32/boards/mm32f327x_mb39/board.mk +++ b/hw/bsp/mm32/boards/mm32f327x_mb39/board.mk @@ -1,12 +1,9 @@ CFLAGS += \ -DHSE_VALUE=8000000 +JLINK_DEVICE = MM32F3273G9P + LD_FILE = $(BOARD_PATH)/flash.ld SRC_S += $(SDK_DIR)/mm32f327x/MM32F327x/Source/GCC_StartAsm/startup_mm32m3ux_u_gcc.S - -# For flash-jlink target -#JLINK_DEVICE = stm32f411ve - -# flash target using on-board stlink -#flash: flash-jlink +flash: flash-jlink diff --git a/hw/bsp/mm32/family.mk b/hw/bsp/mm32/family.mk index 3981e4e41..2e8e595b9 100644 --- a/hw/bsp/mm32/family.mk +++ b/hw/bsp/mm32/family.mk @@ -27,6 +27,3 @@ INC += \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(SDK_DIR)/mm32f327x/MM32F327x/Include \ $(TOP)/$(SDK_DIR)/mm32f327x/MM32F327x/HAL_Lib/Inc - -# flash target using on-board -flash: flash-jlink -- cgit v1.3.1 From 7c7be885b405c7a954a0538e36a2f1b47fdb82f3 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 23:16:21 +0700 Subject: clion setting --- .idea/cmake.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 56c85f21d..2cb86676c 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -65,8 +65,8 @@ - - + + @@ -122,7 +122,8 @@ - + + \ No newline at end of file -- cgit v1.3.1 From f1940439e419e2a1c72a284158e098bca70f279a Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 4 May 2024 10:07:54 +0700 Subject: fix get_deps.py for samd5x_e5x --- tools/get_deps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/get_deps.py b/tools/get_deps.py index 066f3e511..75dd283ea 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -179,7 +179,7 @@ deps_optional = { 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43' 'stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5' 'stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wb' - 'sam3x samd11 samd21 samd51 same5x same7x saml2x samg' + 'sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg' 'tm4c'], 'lib/sct_neopixel': ['https://github.com/gsteiert/sct_neopixel.git', 'e73e04ca63495672d955f9268e003cffe168fcd8', -- cgit v1.3.1 From 666702f478dd91d5d2ea4f194d77f835844a19cd Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 4 May 2024 10:28:47 +0700 Subject: fix ci --- .github/workflows/build_cmake.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index f0937cc85..5140a507f 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -97,7 +97,7 @@ jobs: PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk - name: Upload Artifacts for Hardware Testing (rp2040) - if: matrix.family == 'rp2040' && github.repository_owner == 'hathach' + if: contains(matrix.family, 'rp2040') && github.repository_owner == 'hathach' uses: actions/upload-artifact@v4 with: name: raspberry_pi_pico @@ -105,7 +105,7 @@ jobs: cmake-build/cmake-build-raspberry_pi_pico/*/*/*.elf - name: Upload Artifacts for Hardware Testing (nRF) - if: matrix.family == 'nrf' && github.repository_owner == 'hathach' + if: contains(matrix.family, 'nrf') && github.repository_owner == 'hathach' uses: actions/upload-artifact@v4 with: name: feather_nrf52840_express @@ -113,7 +113,7 @@ jobs: cmake-build/cmake-build-feather_nrf52840_express/*/*/*.elf - name: Upload Artifacts for Hardware Testing (samd51) - if: matrix.family == 'samd5x_e5x' && github.repository_owner == 'hathach' + if: contains(matrix.family, 'samd5x_e5x') && github.repository_owner == 'hathach' uses: actions/upload-artifact@v4 with: name: itsybitsy_m4 -- cgit v1.3.1 From c020a0190d5f22c0f761ce0a5ec4a6e35e4d0662 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 4 May 2024 12:36:40 +0700 Subject: add cmake for f1c100s --- examples/build_system/cmake/cpu/arm1176jzf-s.cmake | 2 + examples/build_system/cmake/cpu/arm926ej-s.cmake | 21 ++++ examples/build_system/make/cpu/arm926ej-s.mk | 9 ++ hw/bsp/f1c100s/board.h | 1 - hw/bsp/f1c100s/board.mk | 52 --------- hw/bsp/f1c100s/boards/f1c100s/board.cmake | 3 + hw/bsp/f1c100s/boards/f1c100s/board.h | 6 + hw/bsp/f1c100s/boards/f1c100s/board.mk | 1 + hw/bsp/f1c100s/f1c100s.c | 130 --------------------- hw/bsp/f1c100s/family.c | 126 ++++++++++++++++++++ hw/bsp/f1c100s/family.cmake | 114 ++++++++++++++++++ hw/bsp/f1c100s/family.mk | 58 +++++++++ src/portable/sunxi/dcd_sunxi_musb.c | 14 ++- 13 files changed, 348 insertions(+), 189 deletions(-) create mode 100644 examples/build_system/cmake/cpu/arm926ej-s.cmake create mode 100644 examples/build_system/make/cpu/arm926ej-s.mk delete mode 100644 hw/bsp/f1c100s/board.h delete mode 100644 hw/bsp/f1c100s/board.mk create mode 100644 hw/bsp/f1c100s/boards/f1c100s/board.cmake create mode 100644 hw/bsp/f1c100s/boards/f1c100s/board.h create mode 100644 hw/bsp/f1c100s/boards/f1c100s/board.mk delete mode 100644 hw/bsp/f1c100s/f1c100s.c create mode 100644 hw/bsp/f1c100s/family.c create mode 100644 hw/bsp/f1c100s/family.cmake create mode 100644 hw/bsp/f1c100s/family.mk diff --git a/examples/build_system/cmake/cpu/arm1176jzf-s.cmake b/examples/build_system/cmake/cpu/arm1176jzf-s.cmake index 11bb52f30..8029e3987 100644 --- a/examples/build_system/cmake/cpu/arm1176jzf-s.cmake +++ b/examples/build_system/cmake/cpu/arm1176jzf-s.cmake @@ -1,6 +1,7 @@ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mcpu=arm1176jzf-s + -ffreestanding ) # set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") @@ -10,6 +11,7 @@ elseif (TOOLCHAIN STREQUAL "clang") -mcpu=arm1176jzf-s -mfpu=none -mfloat-abi=soft + -ffreestanding ) #set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") diff --git a/examples/build_system/cmake/cpu/arm926ej-s.cmake b/examples/build_system/cmake/cpu/arm926ej-s.cmake new file mode 100644 index 000000000..c19b9f8a8 --- /dev/null +++ b/examples/build_system/cmake/cpu/arm926ej-s.cmake @@ -0,0 +1,21 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mcpu=arm926ej-s + -ffreestanding + ) + # set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=arm926ej-s + -mfpu=none + -mfloat-abi=soft + -ffreestanding + ) + #set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + message(FATAL_ERROR "IAR not supported") + +endif () diff --git a/examples/build_system/make/cpu/arm926ej-s.mk b/examples/build_system/make/cpu/arm926ej-s.mk new file mode 100644 index 000000000..5b84f514f --- /dev/null +++ b/examples/build_system/make/cpu/arm926ej-s.mk @@ -0,0 +1,9 @@ +ifeq ($(TOOLCHAIN),gcc) + CFLAGS += \ + -mcpu=arm926ej-s \ + +else ifeq ($(TOOLCHAIN),iar) + #CFLAGS += --cpu cortex-a53 + #ASFLAGS += --cpu cortex-a53 + +endif diff --git a/hw/bsp/f1c100s/board.h b/hw/bsp/f1c100s/board.h deleted file mode 100644 index 0ef9a1700..000000000 --- a/hw/bsp/f1c100s/board.h +++ /dev/null @@ -1 +0,0 @@ -// Nothing valuable here diff --git a/hw/bsp/f1c100s/board.mk b/hw/bsp/f1c100s/board.mk deleted file mode 100644 index 3596e5414..000000000 --- a/hw/bsp/f1c100s/board.mk +++ /dev/null @@ -1,52 +0,0 @@ -MCU_DIR = hw/mcu/allwinner/f1c100s -DEPS_SUBMODULES += hw/mcu/allwinner -DEFINES += -D__ARM32_ARCH__=5 -D__ARM926EJS__ - -CFLAGS += \ - -ffreestanding \ - -std=gnu99 \ - -march=armv5te \ - -mtune=arm926ej-s \ - -mfloat-abi=soft \ - -marm \ - -mno-thumb-interwork \ - -Wno-unused-parameter \ - -Wno-float-equal \ - -DCFG_TUSB_MCU=OPT_MCU_F1C100S \ - -Wno-error=cast-align \ - -Wno-error=address-of-packed-member \ - $(DEFINES) - -LD_FILE = hw/mcu/allwinner/f1c100s/f1c100s.ld -# TODO may skip nanolib -LDFLAGS += -nostdlib -lgcc -specs=nosys.specs -specs=nano.specs - -SRC_C += \ - src/portable/sunxi/dcd_sunxi_musb.c \ - $(MCU_DIR)/machine/sys-uart.c \ - $(MCU_DIR)/machine/exception.c \ - $(MCU_DIR)/machine/sys-clock.c \ - $(MCU_DIR)/machine/sys-copyself.c \ - $(MCU_DIR)/machine/sys-dram.c \ - $(MCU_DIR)/machine/sys-mmu.c \ - $(MCU_DIR)/machine/sys-spi-flash.c \ - $(MCU_DIR)/machine/f1c100s-intc.c \ - $(MCU_DIR)/lib/malloc.c \ - $(MCU_DIR)/lib/printf.c - -SRC_S += \ - $(MCU_DIR)/machine/start.S \ - $(MCU_DIR)/lib/memcpy.S \ - $(MCU_DIR)/lib/memset.S - -INC += \ - $(TOP)/$(MCU_DIR)/include \ - $(TOP)/$(BOARD_PATH) - -# flash target using xfel -flash: flash-xfel - -exec: $(BUILD)/$(PROJECT).bin - xfel ddr - xfel write 0x80000000 $< - xfel exec 0x80000000 diff --git a/hw/bsp/f1c100s/boards/f1c100s/board.cmake b/hw/bsp/f1c100s/boards/f1c100s/board.cmake new file mode 100644 index 000000000..98ed56c57 --- /dev/null +++ b/hw/bsp/f1c100s/boards/f1c100s/board.cmake @@ -0,0 +1,3 @@ +function(update_board TARGET) + # nothing to do +endfunction() diff --git a/hw/bsp/f1c100s/boards/f1c100s/board.h b/hw/bsp/f1c100s/boards/f1c100s/board.h new file mode 100644 index 000000000..3b56a3a57 --- /dev/null +++ b/hw/bsp/f1c100s/boards/f1c100s/board.h @@ -0,0 +1,6 @@ +#ifndef BOARD_H +#define BOARD_H + +// Nothing valuable here + +#endif diff --git a/hw/bsp/f1c100s/boards/f1c100s/board.mk b/hw/bsp/f1c100s/boards/f1c100s/board.mk new file mode 100644 index 000000000..be830bd8c --- /dev/null +++ b/hw/bsp/f1c100s/boards/f1c100s/board.mk @@ -0,0 +1 @@ +# nothing to do diff --git a/hw/bsp/f1c100s/f1c100s.c b/hw/bsp/f1c100s/f1c100s.c deleted file mode 100644 index 272b756f2..000000000 --- a/hw/bsp/f1c100s/f1c100s.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include -#include -#include -#include -#include "bsp/board_api.h" -#include "board.h" - -extern void sys_uart_putc(char c); - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -static void timer_init(void); - -void board_init(void) -{ - arch_local_irq_disable(); - do_init_mem_pool(); - f1c100s_intc_init(); - timer_init(); - printf("Timer INIT done\n"); - arch_local_irq_enable(); -} - -// No LED, no button -void board_led_write(bool state) -{ - -} - -uint32_t board_button_read(void) -{ - return 0; -} - -int board_uart_read(uint8_t* buf, int len) -{ - return 0; -} - -int board_uart_write(void const * buf, int len) -{ - int txsize = len; - while (txsize--) { - sys_uart_putc(*(uint8_t const*)buf); - buf++; - } - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; - -uint32_t board_millis(void) -{ - return system_ticks; -} - -static void timer_handler(void) -{ - volatile uint32_t *temp_addr = (uint32_t *)(0x01C20C00 + 0x04); - - /* clear timer */ - *temp_addr |= 0x01; - - system_ticks++; -} - -static void timer_init(void) { - uint32_t temp; - volatile uint32_t *temp_addr; - - /* reload value */ - temp = 12000000 / 1000; - temp_addr = (uint32_t *)(0x01C20C00 + 0x14); - *temp_addr = temp; - - /* continuous | /2 | 24Mhz | reload*/ - temp = (0x00 << 7) | (0x01 << 4) | (0x01 << 2) | (0x00 << 1); - temp_addr = (uint32_t *)(0x01C20C00 + 0x10); - *temp_addr &= 0xffffff00; - *temp_addr |= temp; - - /* open timer irq */ - temp = 0x01 << 0; - temp_addr = (uint32_t *)(0x01C20C00); - *temp_addr |= temp; - - /* set init value */ - temp_addr = (uint32_t *)(0x01C20C00 + 0x18); - *temp_addr = 0; - - /* begin run timer */ - temp = 0x01 << 0; - temp_addr = (uint32_t *)(0x01C20C00 + 0x10); - *temp_addr |= temp; - - f1c100s_intc_set_isr(F1C100S_IRQ_TIMER0, timer_handler); - f1c100s_intc_enable_irq(F1C100S_IRQ_TIMER0); -} -#else -static void timer_init(void) { } -#endif diff --git a/hw/bsp/f1c100s/family.c b/hw/bsp/f1c100s/family.c new file mode 100644 index 000000000..6df4a0ed8 --- /dev/null +++ b/hw/bsp/f1c100s/family.c @@ -0,0 +1,126 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include +#include +#include +#include +#include "bsp/board_api.h" +#include "board.h" + +extern void sys_uart_putc(char c); + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +static void timer_init(void); + +void board_init(void) { + arch_local_irq_disable(); + do_init_mem_pool(); + f1c100s_intc_init(); + timer_init(); + printf("Timer INIT done\n"); + arch_local_irq_enable(); +} + +// No LED, no button +void board_led_write(bool state) { + (void) state; +} + +uint32_t board_button_read(void) { + return 0; +} + +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const* buf, int len) { + int txsize = len; + while (txsize--) { + sys_uart_putc(*(uint8_t const*) buf); + buf++; + } + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +uint32_t board_millis(void) { + return system_ticks; +} + +static void timer_handler(void) { + volatile uint32_t* temp_addr = (uint32_t*) (0x01C20C00 + 0x04); + + /* clear timer */ + *temp_addr |= 0x01; + + system_ticks++; +} + +static void timer_init(void) { + uint32_t temp; + volatile uint32_t* temp_addr; + + /* reload value */ + temp = 12000000 / 1000; + temp_addr = (uint32_t*) (0x01C20C00 + 0x14); + *temp_addr = temp; + + /* continuous | /2 | 24Mhz | reload*/ + temp = (0x00 << 7) | (0x01 << 4) | (0x01 << 2) | (0x00 << 1); + temp_addr = (uint32_t*) (0x01C20C00 + 0x10); + *temp_addr &= 0xffffff00; + *temp_addr |= temp; + + /* open timer irq */ + temp = 0x01 << 0; + temp_addr = (uint32_t*) (0x01C20C00); + *temp_addr |= temp; + + /* set init value */ + temp_addr = (uint32_t*) (0x01C20C00 + 0x18); + *temp_addr = 0; + + /* begin run timer */ + temp = 0x01 << 0; + temp_addr = (uint32_t*) (0x01C20C00 + 0x10); + *temp_addr |= temp; + + f1c100s_intc_set_isr(F1C100S_IRQ_TIMER0, timer_handler); + f1c100s_intc_enable_irq(F1C100S_IRQ_TIMER0); +} + +#else +static void timer_init(void) { } +#endif diff --git a/hw/bsp/f1c100s/family.cmake b/hw/bsp/f1c100s/family.cmake new file mode 100644 index 000000000..0903a0143 --- /dev/null +++ b/hw/bsp/f1c100s/family.cmake @@ -0,0 +1,114 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/allwinner/f1c100s) + +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR arm926ej-s CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS F1C100S CACHE INTERNAL "") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + # LD_FILE and STARTUP_FILE can be defined in board.cmake + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${SDK_DIR}/f1c100s.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/machine/start.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/lib/malloc.c + ${SDK_DIR}/lib/printf.c + ${SDK_DIR}/lib/memcpy.S + ${SDK_DIR}/lib/memset.S + ${SDK_DIR}/machine/sys-uart.c + ${SDK_DIR}/machine/exception.c + ${SDK_DIR}/machine/sys-clock.c + ${SDK_DIR}/machine/sys-copyself.c + ${SDK_DIR}/machine/sys-dram.c + ${SDK_DIR}/machine/sys-mmu.c + ${SDK_DIR}/machine/sys-spi-flash.c + ${SDK_DIR}/machine/f1c100s-intc.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + + target_compile_definitions(${BOARD_TARGET} PUBLIC + __ARM32_ARCH__=5 + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/include + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -lgcc + --specs=nosys.specs --specs=nano.specs + "LINKER:--defsym=__bss_end__=__bss_end" + "LINKER:--defsym=__bss_start__=__bss_start" + "LINKER:--defsym=end=__bss_end" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_F1C100S ${RTOS}) + target_sources(${TARGET}-tinyusb PRIVATE + ${TOP}/src/portable/sunxi/dcd_sunxi_musb.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/f1c100s/family.mk b/hw/bsp/f1c100s/family.mk new file mode 100644 index 000000000..be416e72e --- /dev/null +++ b/hw/bsp/f1c100s/family.mk @@ -0,0 +1,58 @@ +SDK_DIR = hw/mcu/allwinner/f1c100s + +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= arm926ej-s + +#CFLAGS += \ +# -march=armv5te \ +# -mtune=arm926ej-s \ +# -mfloat-abi=soft \ +# -marm \ + +CFLAGS += \ + -ffreestanding \ + -std=gnu99 \ + -mno-thumb-interwork \ + -D__ARM32_ARCH__=5 \ + -D__ARM926EJS__ \ + -Wno-float-equal \ + -Wno-unused-parameter \ + -DCFG_TUSB_MCU=OPT_MCU_F1C100S \ + -Wno-error=array-bounds \ + +LD_FILE = ${SDK_DIR}/f1c100s.ld + +# TODO may skip nanolib +LDFLAGS += \ + -nostdlib -lgcc \ + --specs=nosys.specs --specs=nano.specs \ + +SRC_C += \ + src/portable/sunxi/dcd_sunxi_musb.c \ + ${SDK_DIR}/machine/sys-uart.c \ + ${SDK_DIR}/machine/exception.c \ + ${SDK_DIR}/machine/sys-clock.c \ + ${SDK_DIR}/machine/sys-copyself.c \ + ${SDK_DIR}/machine/sys-dram.c \ + ${SDK_DIR}/machine/sys-mmu.c \ + ${SDK_DIR}/machine/sys-spi-flash.c \ + ${SDK_DIR}/machine/f1c100s-intc.c \ + ${SDK_DIR}/lib/malloc.c \ + ${SDK_DIR}/lib/printf.c + +SRC_S += \ + ${SDK_DIR}/machine/start.S \ + ${SDK_DIR}/lib/memcpy.S \ + ${SDK_DIR}/lib/memset.S + +INC += \ + $(TOP)/${SDK_DIR}/include \ + $(TOP)/$(BOARD_PATH) + +# flash target using xfel +flash: flash-xfel + +exec: $(BUILD)/$(PROJECT).bin + xfel ddr + xfel write 0x80000000 $< + xfel exec 0x80000000 diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index 6cc1975a8..6f36ad441 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -35,7 +35,9 @@ #include #include #include "musb_def.h" -#include "bsp/board.h" + +//#include "bsp/board_api.h" +extern uint32_t board_millis(void); // TODO remove typedef uint32_t u32; typedef uint16_t u16; @@ -58,7 +60,7 @@ typedef struct TU_ATTR_PACKED typedef struct { - tusb_control_request_t setup_packet; + CFG_TUD_MEM_ALIGN tusb_control_request_t setup_packet; uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ int8_t status_out; pipe_state_t pipe0; @@ -350,7 +352,7 @@ static void USBC_INT_DisableRxEp(u8 ep_index) * INTERNAL FUNCTION DECLARATION *------------------------------------------------------------------*/ -static dcd_data_t _dcd; +CFG_TUD_MEM_ALIGN static dcd_data_t _dcd; static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) { @@ -560,7 +562,7 @@ static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigne static void process_setup_packet(uint8_t rhport) { - uint32_t *p = (uint32_t*)&_dcd.setup_packet; + uint32_t *p = (uint32_t*)(uintptr_t) &_dcd.setup_packet; p[0] = USBC_Readl(USBC_REG_EPFIFO0(USBC0_BASE)); p[1] = USBC_Readl(USBC_REG_EPFIFO0(USBC0_BASE)); @@ -594,7 +596,7 @@ static bool handle_xfer_in(uint_fast8_t ep_addr) if (len) { volatile void* addr = (volatile void*)(USBC_REG_EPFIFO1(USBC0_BASE) + (epnum_minus1 << 2)); if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { - pipe_read_write_packet_ff((tu_fifo_t *)buf, addr, len, TUSB_DIR_IN); + pipe_read_write_packet_ff((tu_fifo_t *)(uintptr_t) buf, addr, len, TUSB_DIR_IN); } else { pipe_write_packet(buf, addr, len); pipe->buf = buf + len; @@ -622,7 +624,7 @@ static bool handle_xfer_out(uint_fast8_t ep_addr) if (len) { volatile void* addr = (volatile void*)(USBC_REG_EPFIFO1(USBC0_BASE) + (epnum_minus1 << 2)); if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { - pipe_read_write_packet_ff((tu_fifo_t *)buf, addr, len, TUSB_DIR_OUT); + pipe_read_write_packet_ff((tu_fifo_t *)(uintptr_t )buf, addr, len, TUSB_DIR_OUT); } else { pipe_read_packet(buf, addr, len); pipe->buf = buf + len; -- cgit v1.3.1 From 3791514908c768df18df1be0afdcb07f2c3596b7 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 4 May 2024 17:23:16 +0700 Subject: add cmake for samg55 --- .github/workflows/build_cmake.yml | 2 +- .idea/cmake.xml | 10 +- hw/bsp/samg/FreeRTOSConfig/FreeRTOSConfig.h | 149 ++++++++++++++ hw/bsp/samg/boards/samg55_xplained/board.cmake | 8 + hw/bsp/samg/boards/samg55_xplained/board.h | 12 ++ hw/bsp/samg/boards/samg55_xplained/board.mk | 6 + .../samg/boards/samg55_xplained/samg55j19_flash.ld | 160 +++++++++++++++ hw/bsp/samg/family.c | 155 +++++++++++++++ hw/bsp/samg/family.cmake | 114 +++++++++++ hw/bsp/samg/family.mk | 45 +++++ hw/bsp/samg/hpl_usart_config.h | 215 +++++++++++++++++++++ hw/bsp/samg/peripheral_clk_config.h | 89 +++++++++ hw/bsp/samg55xplained/board.mk | 56 ------ hw/bsp/samg55xplained/hpl_usart_config.h | 215 --------------------- hw/bsp/samg55xplained/peripheral_clk_config.h | 85 -------- hw/bsp/samg55xplained/samg55j19_flash.ld | 158 --------------- hw/bsp/samg55xplained/samg55xplained.c | 157 --------------- 17 files changed, 960 insertions(+), 676 deletions(-) create mode 100644 hw/bsp/samg/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/samg/boards/samg55_xplained/board.cmake create mode 100644 hw/bsp/samg/boards/samg55_xplained/board.h create mode 100644 hw/bsp/samg/boards/samg55_xplained/board.mk create mode 100644 hw/bsp/samg/boards/samg55_xplained/samg55j19_flash.ld create mode 100644 hw/bsp/samg/family.c create mode 100644 hw/bsp/samg/family.cmake create mode 100644 hw/bsp/samg/family.mk create mode 100644 hw/bsp/samg/hpl_usart_config.h create mode 100644 hw/bsp/samg/peripheral_clk_config.h delete mode 100644 hw/bsp/samg55xplained/board.mk delete mode 100644 hw/bsp/samg55xplained/hpl_usart_config.h delete mode 100644 hw/bsp/samg55xplained/peripheral_clk_config.h delete mode 100644 hw/bsp/samg55xplained/samg55j19_flash.ld delete mode 100644 hw/bsp/samg55xplained/samg55xplained.c diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 5140a507f..050afe48f 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -48,7 +48,7 @@ jobs: - 'nrf' - 'ra' - 'rp2040' - - 'samd11 samd21 saml2x samd5x_e5x' + - 'samd11 samd21 saml2x samd5x_e5x samg' - 'stm32f0' - 'stm32f1' - 'stm32f2' diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 2cb86676c..0e2ca61e4 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -66,7 +66,7 @@ - + @@ -119,11 +119,13 @@ - - + + - + + + \ No newline at end of file diff --git a/hw/bsp/samg/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/samg/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..02223f766 --- /dev/null +++ b/hw/bsp/samg/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + extern uint32_t SystemCoreClock; +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*6*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 4 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + end = .; + } > ram + + /* heap section */ + .heap (NOLOAD): + { + . = ALIGN(8); + _sheap = .; + . = . + HEAP_SIZE; + . = ALIGN(8); + _eheap = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; + _ram_end_ = ORIGIN(ram) + LENGTH(ram) - 1 ; +} diff --git a/hw/bsp/samg/family.c b/hw/bsp/samg/family.c new file mode 100644 index 000000000..63db5739d --- /dev/null +++ b/hw/bsp/samg/family.c @@ -0,0 +1,155 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019, hathach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "sam.h" + +// Suppress warning caused by mcu driver +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif + +#include "peripheral_clk_config.h" +#include "hal/include/hal_init.h" +#include "hal/include/hpl_usart_sync.h" +#include "hpl/pmc/hpl_pmc.h" +#include "hal/include/hal_gpio.h" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#include "bsp/board_api.h" +#include "board.h" + + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ +struct _usart_sync_device edbg_com; + +//------------- IMPLEMENTATION -------------// +void board_init(void) { + init_mcu(); + + _pmc_enable_periph_clock(ID_PIOA); + + /* Disable Watchdog */ + hri_wdt_set_MR_WDDIS_bit(WDT); + + // LED + gpio_set_pin_level(LED_PIN, false); + gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_function(LED_PIN, GPIO_PIN_FUNCTION_OFF); + + // Button + gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP); + gpio_set_pin_function(BUTTON_PIN, GPIO_PIN_FUNCTION_OFF); + + // Uart via EDBG Com + _pmc_enable_periph_clock(ID_FLEXCOM7); + gpio_set_pin_function(UART_RX_PIN, MUX_PA27B_FLEXCOM7_RXD); + gpio_set_pin_function(UART_TX_PIN, MUX_PA28B_FLEXCOM7_TXD); + + _usart_sync_init(&edbg_com, FLEXCOM7); + _usart_sync_set_baud_rate(&edbg_com, CFG_BOARD_UART_BAUDRATE); + _usart_sync_set_mode(&edbg_com, USART_MODE_ASYNCHRONOUS); + _usart_sync_enable(&edbg_com); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer (samd SystemCoreClock may not correct) + SysTick_Config(CONF_CPU_FREQUENCY / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + NVIC_SetPriority(UDP_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + + // USB Pin, Clock init + + /* Clear SYSIO 10 & 11 for USB DM & DP */ + hri_matrix_clear_CCFG_SYSIO_reg(MATRIX, CCFG_SYSIO_SYSIO10 | CCFG_SYSIO_SYSIO11); + + // Enable clock + _pmc_enable_periph_clock(ID_UDP); + + /* USB Device mode & Transceiver active */ + hri_matrix_write_CCFG_USBMR_reg(MATRIX, CCFG_USBMR_USBMODE); +} + +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void UDP_Handler(void) { + #if CFG_TUD_ENABLED + tud_int_handler(0); + #endif +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { + gpio_set_pin_level(LED_PIN, state); +} + +uint32_t board_button_read(void) { + return BUTTON_STATE_ACTIVE == gpio_get_pin_level(BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const* buf, int len) { + uint8_t const* buf8 = (uint8_t const*) buf; + for (int i = 0; i < len; i++) { + while (!_usart_sync_is_ready_to_send(&edbg_com)) {} + _usart_sync_write_byte(&edbg_com, buf8[i]); + } + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; +} + +uint32_t board_millis(void) { + return system_ticks; +} + +#endif + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) { + +} diff --git a/hw/bsp/samg/family.cmake b/hw/bsp/samg/family.cmake new file mode 100644 index 000000000..b88097858 --- /dev/null +++ b/hw/bsp/samg/family.cmake @@ -0,0 +1,114 @@ +include_guard() + +set(SAM_FAMILY samg55) +set(SDK_DIR ${TOP}/hw/mcu/microchip/samg55) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS SAMG CACHE INTERNAL "") +set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -f target/at91samdXX.cfg") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + set(LD_FILE_Clang ${LD_FILE_GNU}) + if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) + message(FATAL_ERROR "LD_FILE_${CMAKE_C_COMPILER_ID} not defined") + endif () + + set(STARTUP_FILE_GNU ${SDK_DIR}/${SAM_FAMILY}/gcc/gcc/startup_${SAM_FAMILY}.c) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/${SAM_FAMILY}/gcc/system_${SAM_FAMILY}.c + ${SDK_DIR}/hal/src/hal_atomic.c + ${SDK_DIR}/hpl/core/hpl_init.c + ${SDK_DIR}/hpl/usart/hpl_usart.c + ${SDK_DIR}/hpl/pmc/hpl_pmc.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${SDK_DIR} + ${SDK_DIR}/config + ${SDK_DIR}/samg55/include + ${SDK_DIR}/hal/include + ${SDK_DIR}/hal/utils/include + ${SDK_DIR}/hpl/core + ${SDK_DIR}/hpl/pio + ${SDK_DIR}/hpl/pmc + ${SDK_DIR}/hri + ${SDK_DIR}/CMSIS/Core/Include + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_SAMG ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/microchip/samg/dcd_samg.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_jlink(${TARGET}) + #family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) +endfunction() diff --git a/hw/bsp/samg/family.mk b/hw/bsp/samg/family.mk new file mode 100644 index 000000000..39b4bc19f --- /dev/null +++ b/hw/bsp/samg/family.mk @@ -0,0 +1,45 @@ +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= cortex-m4 + +SDK_DIR = hw/mcu/microchip/samg55 + +CFLAGS += \ + -flto \ + -DCFG_TUSB_MCU=OPT_MCU_SAMG + +# suppress following warnings from mcu driver +CFLAGS += -Wno-error=undef -Wno-error=null-dereference -Wno-error=redundant-decls + +# SAM driver is flooded with -Wcast-qual which slow down complication significantly +CFLAGS_SKIP += -Wcast-qual + +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ + +SRC_C += \ + src/portable/microchip/samg/dcd_samg.c \ + ${SDK_DIR}/samg55/gcc/gcc/startup_samg55.c \ + ${SDK_DIR}/samg55/gcc/system_samg55.c \ + ${SDK_DIR}/hal/src/hal_atomic.c \ + ${SDK_DIR}/hpl/core/hpl_init.c \ + ${SDK_DIR}/hpl/usart/hpl_usart.c \ + ${SDK_DIR}/hpl/pmc/hpl_pmc.c \ + +INC += \ + $(TOP)/$(FAMILY_PATH) \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/${SDK_DIR} \ + $(TOP)/${SDK_DIR}/config \ + $(TOP)/${SDK_DIR}/samg55/include \ + $(TOP)/${SDK_DIR}/hal/include \ + $(TOP)/${SDK_DIR}/hal/utils/include \ + $(TOP)/${SDK_DIR}/hpl/core \ + $(TOP)/${SDK_DIR}/hpl/pio \ + $(TOP)/${SDK_DIR}/hpl/pmc \ + $(TOP)/${SDK_DIR}/hri \ + $(TOP)/${SDK_DIR}/CMSIS/Core/Include + +# flash using edbg from https://github.com/ataradov/edbg +flash: $(BUILD)/$(PROJECT).bin + edbg --verbose -t samg55 -pv -f $< diff --git a/hw/bsp/samg/hpl_usart_config.h b/hw/bsp/samg/hpl_usart_config.h new file mode 100644 index 000000000..4f2837d2e --- /dev/null +++ b/hw/bsp/samg/hpl_usart_config.h @@ -0,0 +1,215 @@ +/* Auto-generated config file hpl_usart_config.h */ +#ifndef HPL_USART_CONFIG_H +#define HPL_USART_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +#include + +#ifndef CONF_USART_7_ENABLE +#define CONF_USART_7_ENABLE 1 +#endif + +// Basic Configuration + +// Frame parity +// <0x0=>Even parity +// <0x1=>Odd parity +// <0x2=>Parity forced to 0 +// <0x3=>Parity forced to 1 +// <0x4=>No parity +// Parity bit mode for USART frame +// usart_parity +#ifndef CONF_USART_7_PARITY +#define CONF_USART_7_PARITY 0x4 +#endif + +// Character Size +// <0x0=>5 bits +// <0x1=>6 bits +// <0x2=>7 bits +// <0x3=>8 bits +// Data character size in USART frame +// usart_character_size +#ifndef CONF_USART_7_CHSIZE +#define CONF_USART_7_CHSIZE 0x3 +#endif + +// Stop Bit +// <0=>1 stop bit +// <1=>1.5 stop bits +// <2=>2 stop bits +// Number of stop bits in USART frame +// usart_stop_bit +#ifndef CONF_USART_7_SBMODE +#define CONF_USART_7_SBMODE 0 +#endif + +// Clock Output Select +// <0=>The USART does not drive the SCK pin +// <1=>The USART drives the SCK pin if USCLKS does not select the external clock SCK +// Clock Output Select in USART sck, if in usrt master mode, please drive SCK. +// usart_clock_output_select +#ifndef CONF_USART_7_CLKO +#define CONF_USART_7_CLKO 0 +#endif + +// Baud rate <1-3000000> +// USART baud rate setting +// usart_baud_rate +#ifndef CONF_USART_7_BAUD +#define CONF_USART_7_BAUD 9600 +#endif + +// + +// Advanced configuration +// usart_advanced +#ifndef CONF_USART_7_ADVANCED_CONFIG +#define CONF_USART_7_ADVANCED_CONFIG 0 +#endif + +// Channel Mode +// <0=>Normal Mode +// <1=>Automatic Echo +// <2=>Local Loopback +// <3=>Remote Loopback +// Channel mode in USART frame +// usart_channel_mode +#ifndef CONF_USART_7_CHMODE +#define CONF_USART_7_CHMODE 0 +#endif + +// 9 bits character enable +// Enable 9 bits character, this has high priority than 5/6/7/8 bits. +// usart_9bits_enable +#ifndef CONF_USART_7_MODE9 +#define CONF_USART_7_MODE9 0 +#endif + +// Variable Sync +// <0=>User defined configuration +// <1=>sync field is updated when a character is written into US_THR +// Variable Synchronization of Command/Data Sync Start Frarm Delimiter +// variable_sync +#ifndef CONF_USART_7_VAR_SYNC +#define CONF_USART_7_VAR_SYNC 0 +#endif + +// Oversampling Mode +// <0=>16 Oversampling +// <1=>8 Oversampling +// Oversampling Mode in UART mode +// usart__oversampling_mode +#ifndef CONF_USART_7_OVER +#define CONF_USART_7_OVER 0 +#endif + +// Inhibit Non Ack +// <0=>The NACK is generated +// <1=>The NACK is not generated +// Inhibit Non Acknowledge +// usart__inack +#ifndef CONF_USART_7_INACK +#define CONF_USART_7_INACK 1 +#endif + +// Disable Successive NACK +// <0=>NACK is sent on the ISO line as soon as a parity error occurs +// <1=>Many parity errors generate a NACK on the ISO line +// Disable Successive NACK +// usart_dsnack +#ifndef CONF_USART_7_DSNACK +#define CONF_USART_7_DSNACK 0 +#endif + +// Inverted Data +// <0=>Data isn't inverted, nomal mode +// <1=>Data is inverted +// Inverted Data +// usart_invdata +#ifndef CONF_USART_7_INVDATA +#define CONF_USART_7_INVDATA 0 +#endif + +// Maximum Number of Automatic Iteration <0-7> +// Defines the maximum number of iterations in mode ISO7816, protocol T = 0. +// usart_max_iteration +#ifndef CONF_USART_7_MAX_ITERATION +#define CONF_USART_7_MAX_ITERATION 0 +#endif + +// Receive Line Filter enable +// whether the USART filters the receive line using a three-sample filter +// usart_receive_filter_enable +#ifndef CONF_USART_7_FILTER +#define CONF_USART_7_FILTER 0 +#endif + +// Manchester Encoder/Decoder Enable +// whether the USART Manchester Encoder/Decoder +// usart_manchester_filter_enable +#ifndef CONF_USART_7_MAN +#define CONF_USART_7_MAN 0 +#endif + +// Manchester Synchronization Mode +// <0=>The Manchester start bit is a 0 to 1 transition +// <1=>The Manchester start bit is a 1 to 0 transition +// Manchester Synchronization Mode +// usart_manchester_synchronization_mode +#ifndef CONF_USART_7_MODSYNC +#define CONF_USART_7_MODSYNC 0 +#endif + +// Start Frame Delimiter Selector +// <0=>Start frame delimiter is COMMAND or DATA SYNC +// <1=>Start frame delimiter is one bit +// Start Frame Delimiter Selector +// usart_start_frame_delimiter +#ifndef CONF_USART_7_ONEBIT +#define CONF_USART_7_ONEBIT 0 +#endif + +// Fractional Part <0-7> +// Fractional part of the baud rate if baud rate generator is in fractional mode +// usart_arch_fractional +#ifndef CONF_USART_7_FRACTIONAL +#define CONF_USART_7_FRACTIONAL 0x0 +#endif + +// Data Order +// <0=>LSB is transmitted first +// <1=>MSB is transmitted first +// Data order of the data bits in the frame +// usart_arch_msbf +#ifndef CONF_USART_7_MSBF +#define CONF_USART_7_MSBF 0 +#endif + +// + +#define CONF_USART_7_MODE 0x0 + +// Calculate BAUD register value in UART mode +#if CONF_FLEXCOM7_CK_SRC < 3 +#ifndef CONF_USART_7_BAUD_CD +#define CONF_USART_7_BAUD_CD ((CONF_FLEXCOM7_FREQUENCY) / CONF_USART_7_BAUD / 8 / (2 - CONF_USART_7_OVER)) +#endif +#ifndef CONF_USART_7_BAUD_FP +#define CONF_USART_7_BAUD_FP \ + ((CONF_FLEXCOM7_FREQUENCY) / CONF_USART_7_BAUD / (2 - CONF_USART_7_OVER) - 8 * CONF_USART_7_BAUD_CD) +#endif +#elif CONF_FLEXCOM7_CK_SRC == 3 +// No division is active. The value written in US_BRGR has no effect. +#ifndef CONF_USART_7_BAUD_CD +#define CONF_USART_7_BAUD_CD 1 +#endif +#ifndef CONF_USART_7_BAUD_FP +#define CONF_USART_7_BAUD_FP 1 +#endif +#endif + +// <<< end of configuration section >>> + +#endif // HPL_USART_CONFIG_H diff --git a/hw/bsp/samg/peripheral_clk_config.h b/hw/bsp/samg/peripheral_clk_config.h new file mode 100644 index 000000000..2fd817e89 --- /dev/null +++ b/hw/bsp/samg/peripheral_clk_config.h @@ -0,0 +1,89 @@ +/* Auto-generated config file peripheral_clk_config.h */ +#ifndef PERIPHERAL_CLK_CONFIG_H +#define PERIPHERAL_CLK_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +/** + * \def CONF_HCLK_FREQUENCY + * \brief HCLK's Clock frequency + */ +#ifndef CONF_HCLK_FREQUENCY +#define CONF_HCLK_FREQUENCY 8000000 +#endif + +/** + * \def CONF_FCLK_FREQUENCY + * \brief FCLK's Clock frequency + */ +#ifndef CONF_FCLK_FREQUENCY +#define CONF_FCLK_FREQUENCY 8000000 +#endif + +/** + * \def CONF_CPU_FREQUENCY + * \brief CPU's Clock frequency + */ +#ifndef CONF_CPU_FREQUENCY +#define CONF_CPU_FREQUENCY 8000000 +#endif + +/** + * \def CONF_SLCK_FREQUENCY + * \brief Slow Clock frequency + */ +#ifndef CONF_SLCK_FREQUENCY +#define CONF_SLCK_FREQUENCY 32768 +#endif + +/** + * \def CONF_MCK_FREQUENCY + * \brief Master Clock frequency + */ +#ifndef CONF_MCK_FREQUENCY +#define CONF_MCK_FREQUENCY 8000000 +#endif + +// USB Clock Source +// <0=> USB Clock Controller (USB_48M) +// usb_clock_source +// Select the clock source for USB. +#ifndef CONF_UDP_SRC +#define CONF_UDP_SRC 0 +#endif + +/** + * \def CONF_UDP_FREQUENCY + * \brief UDP's Clock frequency + */ +#ifndef CONF_UDP_FREQUENCY +#define CONF_UDP_FREQUENCY 48005120 +#endif + +// FLEXCOM Clock Settings +// FLEXCOM Clock source +// <0=> Master Clock (MCK) +// <1=> MCK / 8 +// <2=> Programmable Clock Controller 6 (PMC_PCK6) +// <2=> Programmable Clock Controller 7 (PMC_PCK7) +// <3=> External Clock +// This defines the clock source for the FLEXCOM, PCK6 is used for FLEXCOM0/1/2/3 and PCK7 is used for FLEXCOM4/5/6/7 +// flexcom_clock_source +#ifndef CONF_FLEXCOM7_CK_SRC +#define CONF_FLEXCOM7_CK_SRC 0 +#endif + +// FLEXCOM External Clock Input on SCK <1-4294967295> +// Inputs the external clock frequency on SCK +// flexcom_clock_freq +#ifndef CONF_FLEXCOM7_SCK_FREQ +#define CONF_FLEXCOM7_SCK_FREQ 10000000 +#endif + +#ifndef CONF_FLEXCOM7_FREQUENCY +#define CONF_FLEXCOM7_FREQUENCY 8000000 +#endif + +// <<< end of configuration section >>> + +#endif // PERIPHERAL_CLK_CONFIG_H diff --git a/hw/bsp/samg55xplained/board.mk b/hw/bsp/samg55xplained/board.mk deleted file mode 100644 index a9328be11..000000000 --- a/hw/bsp/samg55xplained/board.mk +++ /dev/null @@ -1,56 +0,0 @@ -DEPS_SUBMODULES += hw/mcu/microchip -ASF_DIR = hw/mcu/microchip/samg55 - -CFLAGS += \ - -flto \ - -mthumb \ - -mabi=aapcs \ - -mcpu=cortex-m4 \ - -mfloat-abi=hard \ - -mfpu=fpv4-sp-d16 \ - -nostdlib -nostartfiles \ - -D__SAMG55J19__ \ - -DCFG_TUSB_MCU=OPT_MCU_SAMG - -# suppress following warnings from mcu driver -CFLAGS += -Wno-error=undef -Wno-error=null-dereference -Wno-error=redundant-decls - -# SAM driver is flooded with -Wcast-qual which slow down complication significantly -CFLAGS_SKIP += -Wcast-qual - -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs - -# All source paths should be relative to the top level. -LD_FILE = hw/bsp/$(BOARD)/samg55j19_flash.ld - -SRC_C += \ - src/portable/microchip/samg/dcd_samg.c \ - $(ASF_DIR)/samg55/gcc/gcc/startup_samg55.c \ - $(ASF_DIR)/samg55/gcc/system_samg55.c \ - $(ASF_DIR)/hpl/core/hpl_init.c \ - $(ASF_DIR)/hpl/usart/hpl_usart.c \ - $(ASF_DIR)/hpl/pmc/hpl_pmc.c \ - $(ASF_DIR)/hal/src/hal_atomic.c - -INC += \ - $(TOP)/hw/bsp/$(BOARD) \ - $(TOP)/$(ASF_DIR) \ - $(TOP)/$(ASF_DIR)/config \ - $(TOP)/$(ASF_DIR)/samg55/include \ - $(TOP)/$(ASF_DIR)/hal/include \ - $(TOP)/$(ASF_DIR)/hal/utils/include \ - $(TOP)/$(ASF_DIR)/hpl/core \ - $(TOP)/$(ASF_DIR)/hpl/pio \ - $(TOP)/$(ASF_DIR)/hpl/pmc \ - $(TOP)/$(ASF_DIR)/hri \ - $(TOP)/$(ASF_DIR)/CMSIS/Core/Include - -# For freeRTOS port source -FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM4F - -# For flash-jlink target -JLINK_DEVICE = ATSAMG55J19 - -# flash using edbg from https://github.com/ataradov/edbg -flash: $(BUILD)/$(PROJECT).bin - edbg --verbose -t samg55 -pv -f $< diff --git a/hw/bsp/samg55xplained/hpl_usart_config.h b/hw/bsp/samg55xplained/hpl_usart_config.h deleted file mode 100644 index 4f2837d2e..000000000 --- a/hw/bsp/samg55xplained/hpl_usart_config.h +++ /dev/null @@ -1,215 +0,0 @@ -/* Auto-generated config file hpl_usart_config.h */ -#ifndef HPL_USART_CONFIG_H -#define HPL_USART_CONFIG_H - -// <<< Use Configuration Wizard in Context Menu >>> - -#include - -#ifndef CONF_USART_7_ENABLE -#define CONF_USART_7_ENABLE 1 -#endif - -// Basic Configuration - -// Frame parity -// <0x0=>Even parity -// <0x1=>Odd parity -// <0x2=>Parity forced to 0 -// <0x3=>Parity forced to 1 -// <0x4=>No parity -// Parity bit mode for USART frame -// usart_parity -#ifndef CONF_USART_7_PARITY -#define CONF_USART_7_PARITY 0x4 -#endif - -// Character Size -// <0x0=>5 bits -// <0x1=>6 bits -// <0x2=>7 bits -// <0x3=>8 bits -// Data character size in USART frame -// usart_character_size -#ifndef CONF_USART_7_CHSIZE -#define CONF_USART_7_CHSIZE 0x3 -#endif - -// Stop Bit -// <0=>1 stop bit -// <1=>1.5 stop bits -// <2=>2 stop bits -// Number of stop bits in USART frame -// usart_stop_bit -#ifndef CONF_USART_7_SBMODE -#define CONF_USART_7_SBMODE 0 -#endif - -// Clock Output Select -// <0=>The USART does not drive the SCK pin -// <1=>The USART drives the SCK pin if USCLKS does not select the external clock SCK -// Clock Output Select in USART sck, if in usrt master mode, please drive SCK. -// usart_clock_output_select -#ifndef CONF_USART_7_CLKO -#define CONF_USART_7_CLKO 0 -#endif - -// Baud rate <1-3000000> -// USART baud rate setting -// usart_baud_rate -#ifndef CONF_USART_7_BAUD -#define CONF_USART_7_BAUD 9600 -#endif - -// - -// Advanced configuration -// usart_advanced -#ifndef CONF_USART_7_ADVANCED_CONFIG -#define CONF_USART_7_ADVANCED_CONFIG 0 -#endif - -// Channel Mode -// <0=>Normal Mode -// <1=>Automatic Echo -// <2=>Local Loopback -// <3=>Remote Loopback -// Channel mode in USART frame -// usart_channel_mode -#ifndef CONF_USART_7_CHMODE -#define CONF_USART_7_CHMODE 0 -#endif - -// 9 bits character enable -// Enable 9 bits character, this has high priority than 5/6/7/8 bits. -// usart_9bits_enable -#ifndef CONF_USART_7_MODE9 -#define CONF_USART_7_MODE9 0 -#endif - -// Variable Sync -// <0=>User defined configuration -// <1=>sync field is updated when a character is written into US_THR -// Variable Synchronization of Command/Data Sync Start Frarm Delimiter -// variable_sync -#ifndef CONF_USART_7_VAR_SYNC -#define CONF_USART_7_VAR_SYNC 0 -#endif - -// Oversampling Mode -// <0=>16 Oversampling -// <1=>8 Oversampling -// Oversampling Mode in UART mode -// usart__oversampling_mode -#ifndef CONF_USART_7_OVER -#define CONF_USART_7_OVER 0 -#endif - -// Inhibit Non Ack -// <0=>The NACK is generated -// <1=>The NACK is not generated -// Inhibit Non Acknowledge -// usart__inack -#ifndef CONF_USART_7_INACK -#define CONF_USART_7_INACK 1 -#endif - -// Disable Successive NACK -// <0=>NACK is sent on the ISO line as soon as a parity error occurs -// <1=>Many parity errors generate a NACK on the ISO line -// Disable Successive NACK -// usart_dsnack -#ifndef CONF_USART_7_DSNACK -#define CONF_USART_7_DSNACK 0 -#endif - -// Inverted Data -// <0=>Data isn't inverted, nomal mode -// <1=>Data is inverted -// Inverted Data -// usart_invdata -#ifndef CONF_USART_7_INVDATA -#define CONF_USART_7_INVDATA 0 -#endif - -// Maximum Number of Automatic Iteration <0-7> -// Defines the maximum number of iterations in mode ISO7816, protocol T = 0. -// usart_max_iteration -#ifndef CONF_USART_7_MAX_ITERATION -#define CONF_USART_7_MAX_ITERATION 0 -#endif - -// Receive Line Filter enable -// whether the USART filters the receive line using a three-sample filter -// usart_receive_filter_enable -#ifndef CONF_USART_7_FILTER -#define CONF_USART_7_FILTER 0 -#endif - -// Manchester Encoder/Decoder Enable -// whether the USART Manchester Encoder/Decoder -// usart_manchester_filter_enable -#ifndef CONF_USART_7_MAN -#define CONF_USART_7_MAN 0 -#endif - -// Manchester Synchronization Mode -// <0=>The Manchester start bit is a 0 to 1 transition -// <1=>The Manchester start bit is a 1 to 0 transition -// Manchester Synchronization Mode -// usart_manchester_synchronization_mode -#ifndef CONF_USART_7_MODSYNC -#define CONF_USART_7_MODSYNC 0 -#endif - -// Start Frame Delimiter Selector -// <0=>Start frame delimiter is COMMAND or DATA SYNC -// <1=>Start frame delimiter is one bit -// Start Frame Delimiter Selector -// usart_start_frame_delimiter -#ifndef CONF_USART_7_ONEBIT -#define CONF_USART_7_ONEBIT 0 -#endif - -// Fractional Part <0-7> -// Fractional part of the baud rate if baud rate generator is in fractional mode -// usart_arch_fractional -#ifndef CONF_USART_7_FRACTIONAL -#define CONF_USART_7_FRACTIONAL 0x0 -#endif - -// Data Order -// <0=>LSB is transmitted first -// <1=>MSB is transmitted first -// Data order of the data bits in the frame -// usart_arch_msbf -#ifndef CONF_USART_7_MSBF -#define CONF_USART_7_MSBF 0 -#endif - -// - -#define CONF_USART_7_MODE 0x0 - -// Calculate BAUD register value in UART mode -#if CONF_FLEXCOM7_CK_SRC < 3 -#ifndef CONF_USART_7_BAUD_CD -#define CONF_USART_7_BAUD_CD ((CONF_FLEXCOM7_FREQUENCY) / CONF_USART_7_BAUD / 8 / (2 - CONF_USART_7_OVER)) -#endif -#ifndef CONF_USART_7_BAUD_FP -#define CONF_USART_7_BAUD_FP \ - ((CONF_FLEXCOM7_FREQUENCY) / CONF_USART_7_BAUD / (2 - CONF_USART_7_OVER) - 8 * CONF_USART_7_BAUD_CD) -#endif -#elif CONF_FLEXCOM7_CK_SRC == 3 -// No division is active. The value written in US_BRGR has no effect. -#ifndef CONF_USART_7_BAUD_CD -#define CONF_USART_7_BAUD_CD 1 -#endif -#ifndef CONF_USART_7_BAUD_FP -#define CONF_USART_7_BAUD_FP 1 -#endif -#endif - -// <<< end of configuration section >>> - -#endif // HPL_USART_CONFIG_H diff --git a/hw/bsp/samg55xplained/peripheral_clk_config.h b/hw/bsp/samg55xplained/peripheral_clk_config.h deleted file mode 100644 index 6d390f388..000000000 --- a/hw/bsp/samg55xplained/peripheral_clk_config.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Auto-generated config file peripheral_clk_config.h */ -#ifndef PERIPHERAL_CLK_CONFIG_H -#define PERIPHERAL_CLK_CONFIG_H - -// <<< Use Configuration Wizard in Context Menu >>> - -/** - * \def CONF_HCLK_FREQUENCY - * \brief HCLK's Clock frequency - */ -#ifndef CONF_HCLK_FREQUENCY -#define CONF_HCLK_FREQUENCY 8000000 -#endif - -/** - * \def CONF_FCLK_FREQUENCY - * \brief FCLK's Clock frequency - */ -#ifndef CONF_FCLK_FREQUENCY -#define CONF_FCLK_FREQUENCY 8000000 -#endif - -/** - * \def CONF_CPU_FREQUENCY - * \brief CPU's Clock frequency - */ -#ifndef CONF_CPU_FREQUENCY -#define CONF_CPU_FREQUENCY 8000000 -#endif - -/** - * \def CONF_SLCK_FREQUENCY - * \brief Slow Clock frequency - */ -#define CONF_SLCK_FREQUENCY 32768 - -/** - * \def CONF_MCK_FREQUENCY - * \brief Master Clock frequency - */ -#define CONF_MCK_FREQUENCY 8000000 - -// USB Clock Source -// <0=> USB Clock Controller (USB_48M) -// usb_clock_source -// Select the clock source for USB. -#ifndef CONF_UDP_SRC -#define CONF_UDP_SRC 0 -#endif - -/** - * \def CONF_UDP_FREQUENCY - * \brief UDP's Clock frequency - */ -#ifndef CONF_UDP_FREQUENCY -#define CONF_UDP_FREQUENCY 48005120 -#endif - -// FLEXCOM Clock Settings -// FLEXCOM Clock source -// <0=> Master Clock (MCK) -// <1=> MCK / 8 -// <2=> Programmable Clock Controller 6 (PMC_PCK6) -// <2=> Programmable Clock Controller 7 (PMC_PCK7) -// <3=> External Clock -// This defines the clock source for the FLEXCOM, PCK6 is used for FLEXCOM0/1/2/3 and PCK7 is used for FLEXCOM4/5/6/7 -// flexcom_clock_source -#ifndef CONF_FLEXCOM7_CK_SRC -#define CONF_FLEXCOM7_CK_SRC 0 -#endif - -// FLEXCOM External Clock Input on SCK <1-4294967295> -// Inputs the external clock frequency on SCK -// flexcom_clock_freq -#ifndef CONF_FLEXCOM7_SCK_FREQ -#define CONF_FLEXCOM7_SCK_FREQ 10000000 -#endif - -#ifndef CONF_FLEXCOM7_FREQUENCY -#define CONF_FLEXCOM7_FREQUENCY 8000000 -#endif - -// <<< end of configuration section >>> - -#endif // PERIPHERAL_CLK_CONFIG_H diff --git a/hw/bsp/samg55xplained/samg55j19_flash.ld b/hw/bsp/samg55xplained/samg55j19_flash.ld deleted file mode 100644 index a222b919b..000000000 --- a/hw/bsp/samg55xplained/samg55j19_flash.ld +++ /dev/null @@ -1,158 +0,0 @@ -/** - * \file - * - * \brief GCC linker script (flash) for ATSAMG55J19 - * - * Copyright (c) 2017 Atmel Corporation, a wholly owned subsidiary of Microchip Technology Inc. - * - * \license_start - * - * \page License - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * \license_stop - * - */ - -/*------------------------------------------------------------------------------ - * Linker script for running in internal FLASH on the ATSAMG55J19 - *----------------------------------------------------------------------------*/ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) - -/* Memory Spaces Definitions */ -MEMORY -{ - rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00080000 /* rom, 524288K */ - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00028000 /* ram, 163840K */ -} - -/* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; - -/* The heapsize used by the application. NOTE: you need to adjust according to your application. */ -HEAP_SIZE = DEFINED(HEAP_SIZE) ? HEAP_SIZE : DEFINED(__heap_size__) ? __heap_size__ : 0x0200; - -/* Section Definitions */ -SECTIONS -{ - .text : - { - . = ALIGN(4); - _sfixed = .; - KEEP(*(.vectors .vectors.*)) - *(.text .text.* .gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) - *(.rodata .rodata* .gnu.linkonce.r.*) - *(.ARM.extab* .gnu.linkonce.armextab.*) - - /* Support C constructors, and C destructors in both user code - and the C library. This also provides support for C++ code. */ - . = ALIGN(4); - KEEP(*(.init)) - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(0x4); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - - . = ALIGN(4); - _efixed = .; /* End of text section */ - } > rom - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - PROVIDE_HIDDEN (__exidx_start = .); - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > rom - PROVIDE_HIDDEN (__exidx_end = .); - - . = ALIGN(4); - _etext = .; - - .relocate : AT (_etext) - { - . = ALIGN(4); - _srelocate = .; - *(.ramfunc .ramfunc.*); - *(.data .data.*); - . = ALIGN(4); - _erelocate = .; - } > ram - - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = . ; - _szero = .; - *(.bss .bss.*) - *(COMMON) - . = ALIGN(4); - _ebss = . ; - _ezero = .; - end = .; - } > ram - - /* heap section */ - .heap (NOLOAD): - { - . = ALIGN(8); - _sheap = .; - . = . + HEAP_SIZE; - . = ALIGN(8); - _eheap = .; - } > ram - - /* stack section */ - .stack (NOLOAD): - { - . = ALIGN(8); - _sstack = .; - . = . + STACK_SIZE; - . = ALIGN(8); - _estack = .; - } > ram - - . = ALIGN(4); - _end = . ; - _ram_end_ = ORIGIN(ram) + LENGTH(ram) - 1 ; -} diff --git a/hw/bsp/samg55xplained/samg55xplained.c b/hw/bsp/samg55xplained/samg55xplained.c deleted file mode 100644 index 2ac0c0a29..000000000 --- a/hw/bsp/samg55xplained/samg55xplained.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019, hathach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -#include "sam.h" -#include "bsp/board_api.h" - -#include "peripheral_clk_config.h" -#include "hal/include/hal_init.h" -#include "hal/include/hpl_usart_sync.h" -#include "hpl/pmc/hpl_pmc.h" -#include "hal/include/hal_gpio.h" - - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ - -#define LED_PIN GPIO(GPIO_PORTA, 6) - -#define BUTTON_PIN GPIO(GPIO_PORTA, 2) -#define BUTTON_STATE_ACTIVE 0 - -#define UART_TX_PIN GPIO(GPIO_PORTA, 28) -#define UART_RX_PIN GPIO(GPIO_PORTA, 27) - -struct _usart_sync_device edbg_com; - -//------------- IMPLEMENTATION -------------// -void board_init(void) -{ - init_mcu(); - - _pmc_enable_periph_clock(ID_PIOA); - - /* Disable Watchdog */ - hri_wdt_set_MR_WDDIS_bit(WDT); - - // LED - gpio_set_pin_level(LED_PIN, false); - gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); - gpio_set_pin_function(LED_PIN, GPIO_PIN_FUNCTION_OFF); - - // Button - gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); - gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP); - gpio_set_pin_function(BUTTON_PIN, GPIO_PIN_FUNCTION_OFF); - - // Uart via EDBG Com - _pmc_enable_periph_clock(ID_FLEXCOM7); - gpio_set_pin_function(UART_RX_PIN, MUX_PA27B_FLEXCOM7_RXD); - gpio_set_pin_function(UART_TX_PIN, MUX_PA28B_FLEXCOM7_TXD); - - _usart_sync_init(&edbg_com, FLEXCOM7); - _usart_sync_set_baud_rate(&edbg_com, CFG_BOARD_UART_BAUDRATE); - _usart_sync_set_mode(&edbg_com, USART_MODE_ASYNCHRONOUS); - _usart_sync_enable(&edbg_com); - -#if CFG_TUSB_OS == OPT_OS_NONE - // 1ms tick timer (samd SystemCoreClock may not correct) - SysTick_Config(CONF_CPU_FREQUENCY / 1000); -#endif - - // USB Pin, Clock init - - /* Clear SYSIO 10 & 11 for USB DM & DP */ - hri_matrix_clear_CCFG_SYSIO_reg(MATRIX, CCFG_SYSIO_SYSIO10 | CCFG_SYSIO_SYSIO11); - - // Enable clock - _pmc_enable_periph_clock(ID_UDP); - - /* USB Device mode & Transceiver active */ - hri_matrix_write_CCFG_USBMR_reg(MATRIX, CCFG_USBMR_USBMODE); -} - -//--------------------------------------------------------------------+ -// USB Interrupt Handler -//--------------------------------------------------------------------+ -void UDP_Handler(void) -{ - #if CFG_TUD_ENABLED - tud_int_handler(0); - #endif -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) -{ - gpio_set_pin_level(LED_PIN, state); -} - -uint32_t board_button_read(void) -{ - return BUTTON_STATE_ACTIVE == gpio_get_pin_level(BUTTON_PIN); -} - -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; - return 0; -} - -int board_uart_write(void const * buf, int len) -{ - uint8_t const * buf8 = (uint8_t const *) buf; - for(int i=0; i Date: Sun, 5 May 2024 20:33:01 +0200 Subject: minor changes due to CR with HiFiPhile --- src/class/net/ncm.h | 50 ++++++++++++++++++++++++++-------------------- src/class/net/ncm_device.c | 6 +++--- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/class/net/ncm.h b/src/class/net/ncm.h index c768192a5..cf4daf96c 100644 --- a/src/class/net/ncm.h +++ b/src/class/net/ncm.h @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) + * Copyright (c) 2024, Hardy Griech * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,42 +30,47 @@ #define _TUSB_NCM_H_ #include "common/tusb_common.h" - +#include "lwipopts.h" #ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE - /// must be >> MTU - #define CFG_TUD_NCM_IN_NTB_MAX_SIZE 3200 + #define CFG_TUD_NCM_IN_NTB_MAX_SIZE (2 * TCP_MSS + 100) #endif #ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE - /// must be >> MTU - #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE 3200 + #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE (2 * TCP_MSS + 100) #endif #ifndef CFG_TUD_NCM_OUT_NTB_N - /// number of ntb buffers for reception side - /// 1 - good performance - /// 2 - up to 30% more performance with iperf with small packets - /// >2 - no performance gain - #define CFG_TUD_NCM_OUT_NTB_N 2 + /// number of NTB buffers for reception side + /// 1 - good performance + /// 2 - up to 30% more performance with iperf with small packets + /// >2 - no performance gain + /// -> for performance optimizations this parameter could be increased with the cost of additional RAM requirements + #define CFG_TUD_NCM_OUT_NTB_N 1 #endif #ifndef CFG_TUD_NCM_IN_NTB_N - /// number of ntb buffers for transmission side - /// 1 - good performance but SystemView shows lost events (on load test) - /// 2 - up to 50% more performance with iperf with small packets, "tud_network_can_xmit: request blocked" - /// happens from time to time with SystemView - /// 3 - "tud_network_can_xmit: request blocked" never happens - /// >2 - no performance gain - #define CFG_TUD_NCM_IN_NTB_N 3 + /// number of NTB buffers for transmission side + /// 1 - good performance but SystemView shows lost events (on load test) + /// 2 - up to 50% more performance with iperf with small packets, "tud_network_can_xmit: request blocked" + /// happens from time to time with SystemView + /// 3 - "tud_network_can_xmit: request blocked" never happens + /// >2 - no performance gain + /// -> for performance optimizations this parameter could be increased with the cost of additional RAM requirements + #define CFG_TUD_NCM_IN_NTB_N 1 +#endif + +#ifndef CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB + /// this is for the transmission side for allocation of \a ndp16_datagram_t + #define CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB 8 #endif -#ifndef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB - /// this is for the transmission size for allocation of \a ndp16_datagram_t - #define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 8 +#ifndef CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB + /// this tells the host how many datagrams it is allowed to put into an NTB + #define CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB 6 #endif #ifndef CFG_TUD_NCM_ALIGNMENT - #define CFG_TUD_NCM_ALIGNMENT 4 + #define CFG_TUD_NCM_ALIGNMENT 4 #endif #if (CFG_TUD_NCM_ALIGNMENT != 4) #error "CFG_TUD_NCM_ALIGNMENT must be 4, otherwise the headers and start of datagrams have to be aligned (which they are currently not)" @@ -136,7 +142,7 @@ typedef union TU_ATTR_PACKED { struct { nth16_t nth; ndp16_t ndp; - ndp16_datagram_t ndp_datagram[CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + 1]; + ndp16_datagram_t ndp_datagram[CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB + 1]; }; uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; } xmit_ntb_t; diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 829161865..40f70dc3f 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -1,8 +1,8 @@ /* * The MIT License (MIT) * - * Copyright (c) 2023 Hardy Griech * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2024 Hardy Griech * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -126,7 +126,7 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par .wNdbOutDivisor = 4, .wNdbOutPayloadRemainder = 0, .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, - .wNtbOutMaxDatagrams = 6 // 0=no limit + .wNtbOutMaxDatagrams = CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB, }; //----------------------------------------------------------------------------- @@ -371,7 +371,7 @@ static bool xmit_requested_datagram_fits_into_current_ntb(uint16_t datagram_size if (ncm_interface.xmit_glue_ntb == NULL) { return false; } - if (ncm_interface.xmit_glue_ntb_datagram_ndx >= CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB) { + if (ncm_interface.xmit_glue_ntb_datagram_ndx >= CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB) { return false; } if (ncm_interface.xmit_glue_ntb->nth.wBlockLength + datagram_size + XMIT_ALIGN_OFFSET(datagram_size) > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { -- cgit v1.3.1 From cc70958c16f4b88c0e48590d32189c870091547e Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 5 May 2024 21:18:57 +0200 Subject: mostly comments --- src/class/net/ncm_device.c | 56 +++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 40f70dc3f..05cebf94e 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -79,7 +79,7 @@ typedef struct { uint8_t rhport; //!< storage of \a rhport because some callbacks are done without it // recv handling - CFG_TUSB_MEM_ALIGN recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs + CFG_TUSB_MEM_ALIGN recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs recv_ntb_t *recv_free_ntb[RECV_NTB_N]; //!< free list of recv NTBs recv_ntb_t *recv_ready_ntb[RECV_NTB_N]; //!< NTBs waiting for transmission to glue logic recv_ntb_t *recv_tinyusb_ntb; //!< buffer for the running transfer TinyUSB -> driver @@ -87,7 +87,7 @@ typedef struct { uint16_t recv_glue_ntb_datagram_ndx; //!< index into \a recv_glue_ntb_datagram // xmit handling - CFG_TUSB_MEM_ALIGN xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs + CFG_TUSB_MEM_ALIGN xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs xmit_ntb_t *xmit_free_ntb[XMIT_NTB_N]; //!< free list of xmit NTBs xmit_ntb_t *xmit_ready_ntb[XMIT_NTB_N]; //!< NTBs waiting for transmission to TinyUSB xmit_ntb_t *xmit_tinyusb_ntb; //!< buffer for the running transfer driver -> TinyUSB @@ -129,6 +129,18 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par .wNtbOutMaxDatagrams = CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB, }; +// Some confusing remarks about wNtbOutMaxDatagrams... +// ==1 -> SystemView packets/s goes up to 2000 and events are lost during startup +// ==0 -> SystemView runs fine, iperf shows in wireshark a lot of error +// ==6 -> SystemView runs fine, iperf also +// >6 -> iperf starts to show errors +// -> 6 seems to be the best value. Why? Don't know, perhaps only on my system? +// switch \a TU_LOG2 on to see interesting values for this. +// +// iperf: for MSS in 100 200 400 800 1200 1450 1500; do iperf -c 192.168.14.1 -e -i 1 -M $MSS -l 8192 -P 1; sleep 2; done +// sysview: SYSTICKS_PER_SEC=35000, IDLE_US=1000, PRINT_MOD=1000 +// + //----------------------------------------------------------------------------- // // everything about notifications @@ -340,7 +352,7 @@ static void xmit_start_if_possible(uint8_t rhport) ncm_interface.xmit_glue_ntb = NULL; } -#ifdef DEBUG_OUT_ENABLED +#if CFG_TUSB_DEBUG >= 3 { uint16_t len = ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength; TU_LOG3(" %d\n", len); @@ -708,7 +720,7 @@ bool tud_network_can_xmit(uint16_t size) return true; } xmit_start_if_possible(ncm_interface.rhport); - TU_LOG2("tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) + TU_LOG2("(II) tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) return false; } // tud_network_can_xmit @@ -796,10 +808,18 @@ void netd_init(void) } } // netd_init -bool netd_deinit(void) { - return true; + + +bool netd_deinit(void) +/** + * Deinit driver + */ +{ + return true; } + + void netd_reset(uint8_t rhport) /** * Resets the port. @@ -947,12 +967,14 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t } switch (request->bmRequestType_bit.type) { - case TUSB_REQ_TYPE_STANDARD: { + case TUSB_REQ_TYPE_STANDARD: + TU_LOG3(" TUSB_REQ_TYPE_STANDARD: %d\n", request->bRequest); + switch (request->bRequest) { case TUSB_REQ_GET_INTERFACE: { TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex, false); - TU_LOG3(" TUSB_REQ_GET_INTERFACE - %d\n", ncm_interface.itf_data_alt); + TU_LOG3(" TUSB_REQ_GET_INTERFACE - %d\n", ncm_interface.itf_data_alt); tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); } break; @@ -961,7 +983,7 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex && request->wValue < 2, false); ncm_interface.itf_data_alt = (uint8_t)request->wValue; - TU_LOG3(" TUSB_REQ_SET_INTERFACE - %d %d %d\n", ncm_interface.itf_data_alt, request->wIndex, ncm_interface.itf_num); + TU_LOG3(" TUSB_REQ_SET_INTERFACE - %d %d %d\n", ncm_interface.itf_data_alt, request->wIndex, ncm_interface.itf_num); if (ncm_interface.itf_data_alt == 1) { tud_network_recv_renew_r(rhport); @@ -975,15 +997,14 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t default: return false; } - } - break; + break; - case TUSB_REQ_TYPE_CLASS: { + case TUSB_REQ_TYPE_CLASS: TU_VERIFY(ncm_interface.itf_num == request->wIndex, false); - switch (request->bRequest) { + TU_LOG3(" TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); - case NCM_GET_NTB_PARAMETERS: { + if (request->bRequest == NCM_GET_NTB_PARAMETERS) { // transfer NTB parameters to host. // TODO can one assume, that tud_control_xfer() succeeds? TU_LOG3(" NCM_GET_NTB_PARAMETERS\n"); @@ -991,13 +1012,6 @@ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t } break; - // unsupported request - default: - return false ; - - } - } - break; // unsupported request default: return false ; -- cgit v1.3.1 From 02ec4866105eca3f95e7392e538caf97ebb902b4 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 5 May 2024 22:01:09 +0200 Subject: Fix spurious EP0 completion. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index c4b1956ce..8c3a6ec61 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1081,22 +1081,26 @@ static void handle_epout_irq(uint8_t rhport) { } else if (doepint & DOEPINT_OTEPSPR) { epout->doepint = DOEPINT_OTEPSPR; } else { - // EP0 can only handle one packet - if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { - // Schedule another packet to be received. - edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_STPKTRX; } else { - if(dma_enabled(rhport)) { - // Fix packet length - uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; - xfer->total_len -= remain; - // this is ZLP, so prepare EP0 for next setup - if(n == 0 && xfer->total_len == 0) { - dma_stpkt_rx(rhport); + // EP0 can only handle one packet + if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + // Schedule another packet to be received. + edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + } else { + if(dma_enabled(rhport)) { + // Fix packet length + uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; + xfer->total_len -= remain; + // this is ZLP, so prepare EP0 for next setup + if(n == 0 && xfer->total_len == 0) { + dma_stpkt_rx(rhport); + } } - } - dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + } } } } -- cgit v1.3.1 From d79c71abf593b7fde1e83eac074900216643dbff Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 May 2024 10:52:52 +0700 Subject: update flash openocd --- hw/bsp/family_support.cmake | 6 +++--- hw/bsp/rp2040/family.cmake | 2 +- hw/bsp/samd11/family.cmake | 2 +- hw/bsp/samd21/family.cmake | 2 +- hw/bsp/samd5x_e5x/family.cmake | 2 +- hw/bsp/samg/boards/samg55_xplained/board.mk | 4 ++++ hw/bsp/samg/family.cmake | 4 ++-- hw/bsp/samg/family.mk | 2 +- hw/bsp/saml2x/family.cmake | 2 +- hw/bsp/tm4c/family.cmake | 2 +- 10 files changed, 16 insertions(+), 12 deletions(-) diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 5f0653646..bac1ecb5f 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -415,17 +415,17 @@ endfunction() # Add flash openocd target -function(family_flash_openocd TARGET CLI_OPTIONS) +function(family_flash_openocd TARGET) if (NOT DEFINED OPENOCD) set(OPENOCD openocd) endif () - separate_arguments(CLI_OPTIONS_LIST UNIX_COMMAND ${CLI_OPTIONS}) + separate_arguments(OPENOCD_OPTION_LIST UNIX_COMMAND ${OPENOCD_OPTION}) # note skip verify since it has issue with rp2040 add_custom_target(${TARGET}-openocd DEPENDS ${TARGET} - COMMAND ${OPENOCD} ${CLI_OPTIONS_LIST} -c "program $ reset exit" + COMMAND ${OPENOCD} ${OPENOCD_OPTION_LIST} -c "program $ reset exit" VERBATIM ) endfunction() diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index a298e684b..b41d7fbea 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -179,7 +179,7 @@ function(family_configure_target TARGET RTOS) pico_enable_stdio_uart(${TARGET} 1) target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_board${RTOS_SUFFIX} tinyusb_additions) - family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) + family_flash_openocd(${TARGET}) family_flash_jlink(${TARGET}) endfunction() diff --git a/hw/bsp/samd11/family.cmake b/hw/bsp/samd11/family.cmake index c0d1f5a7e..c9ccc86f8 100644 --- a/hw/bsp/samd11/family.cmake +++ b/hw/bsp/samd11/family.cmake @@ -112,5 +112,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) - #family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) + #family_flash_openocd(${TARGET}) endfunction() diff --git a/hw/bsp/samd21/family.cmake b/hw/bsp/samd21/family.cmake index e081aedaf..c836b85d9 100644 --- a/hw/bsp/samd21/family.cmake +++ b/hw/bsp/samd21/family.cmake @@ -108,5 +108,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) - #family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) + #family_flash_openocd(${TARGET}) endfunction() diff --git a/hw/bsp/samd5x_e5x/family.cmake b/hw/bsp/samd5x_e5x/family.cmake index 6d64a5fe4..fd95ce10e 100644 --- a/hw/bsp/samd5x_e5x/family.cmake +++ b/hw/bsp/samd5x_e5x/family.cmake @@ -105,5 +105,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) - #family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) + #family_flash_openocd(${TARGET}) endfunction() diff --git a/hw/bsp/samg/boards/samg55_xplained/board.mk b/hw/bsp/samg/boards/samg55_xplained/board.mk index 4481cbaf7..8751ff63e 100644 --- a/hw/bsp/samg/boards/samg55_xplained/board.mk +++ b/hw/bsp/samg/boards/samg55_xplained/board.mk @@ -4,3 +4,7 @@ JLINK_DEVICE = ATSAMG55J19 # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/samg55j19_flash.ld + +OPENOCD_OPTION = -f board/atmel_samg55_xplained_pro.cfg + +flash: flash-openocd diff --git a/hw/bsp/samg/family.cmake b/hw/bsp/samg/family.cmake index b88097858..1cc715ce6 100644 --- a/hw/bsp/samg/family.cmake +++ b/hw/bsp/samg/family.cmake @@ -11,7 +11,7 @@ set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS SAMG CACHE INTERNAL "") -set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -f target/at91samdXX.cfg") +set(OPENOCD_OPTION "-f board/atmel_samg55_xplained_pro.cfg") #------------------------------------ # BOARD_TARGET @@ -110,5 +110,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) - #family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) + family_flash_openocd(${TARGET}) endfunction() diff --git a/hw/bsp/samg/family.mk b/hw/bsp/samg/family.mk index 39b4bc19f..d5d2e6122 100644 --- a/hw/bsp/samg/family.mk +++ b/hw/bsp/samg/family.mk @@ -41,5 +41,5 @@ INC += \ $(TOP)/${SDK_DIR}/CMSIS/Core/Include # flash using edbg from https://github.com/ataradov/edbg -flash: $(BUILD)/$(PROJECT).bin +flash-edbg: $(BUILD)/$(PROJECT).bin edbg --verbose -t samg55 -pv -f $< diff --git a/hw/bsp/saml2x/family.cmake b/hw/bsp/saml2x/family.cmake index 8390cdc9c..2338d1916 100644 --- a/hw/bsp/saml2x/family.cmake +++ b/hw/bsp/saml2x/family.cmake @@ -112,5 +112,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) - #family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) + #family_flash_openocd(${TARGET}) endfunction() diff --git a/hw/bsp/tm4c/family.cmake b/hw/bsp/tm4c/family.cmake index f7ab2fb28..86db985d6 100644 --- a/hw/bsp/tm4c/family.cmake +++ b/hw/bsp/tm4c/family.cmake @@ -91,5 +91,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_add_bin_hex(${TARGET}) - family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) + family_flash_openocd(${TARGET}) endfunction() -- cgit v1.3.1 From 82547372d1a83f03d137a20f71b2d60a5702a75a Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Mon, 6 May 2024 08:42:08 +0200 Subject: edpt_dma_start() is called during interrupt time as well, dcd_edpt_xfer() needs DI/EI at one point --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 2fe721d6b..805eb1dda 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -77,6 +77,18 @@ #endif #endif +/** disable interrupts */ +#define DISABLE_IRQ() \ + uint32_t prim = __get_PRIMASK(); \ + __disable_irq(); + +/** (re)enable interrupts */ +#define ENABLE_IRQ() \ + if (!prim) \ + { \ + __enable_irq(); \ + } + /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ @@ -147,7 +159,7 @@ static void start_dma(volatile uint32_t* reg_startep) { static void edpt_dma_start(volatile uint32_t* reg_startep) { if (atomic_flag_test_and_set(&_dcd.dma_running)) { - usbd_defer_func((osal_task_func_t)(uintptr_t ) edpt_dma_start, (void*) (uintptr_t) reg_startep, true); + usbd_defer_func((osal_task_func_t)(uintptr_t ) edpt_dma_start, (void*) (uintptr_t) reg_startep, is_in_isr()); } else { start_dma(reg_startep); } @@ -434,11 +446,15 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE)); if (control_status) { + DISABLE_IRQ(); + // Status Phase also requires EasyDMA has to be available as well !!!! edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS); // The nRF doesn't interrupt on status transmit so we queue up a success response. dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, is_in_isr()); + + ENABLE_IRQ(); } else if (dir == TUSB_DIR_OUT) { xfer->started = true; if (epnum == 0) { -- cgit v1.3.1 From 497785393de5500d99ff80110040c04039bd072f Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 May 2024 17:14:35 +0700 Subject: add cmake for mm32, remove mm32 bluepill since it is custom/reworked board (not available for order) --- .github/workflows/build_cmake.yml | 1 + hw/bsp/mm32/FreeRTOSConfig/FreeRTOSConfig.h | 150 +++++++++++++++++ hw/bsp/mm32/boards/mm32f327x_bluepillplus/board.mk | 11 -- hw/bsp/mm32/boards/mm32f327x_bluepillplus/flash.ld | 163 ------------------ .../mm32f327x_bluepillplus.c | 182 --------------------- hw/bsp/mm32/boards/mm32f327x_mb39/board.cmake | 10 ++ hw/bsp/mm32/boards/mm32f327x_mb39/board.h | 19 +++ hw/bsp/mm32/boards/mm32f327x_mb39/board.mk | 2 +- hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c | 171 ------------------- .../mm32/boards/mm32f327x_pitaya_lite/board.cmake | 10 ++ hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.h | 14 ++ hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.mk | 5 +- .../mm32f327x_pitaya_lite/mm32f327x_pitaya_lite.c | 182 --------------------- hw/bsp/mm32/family.c | 169 +++++++++++++++++++ hw/bsp/mm32/family.cmake | 101 ++++++++++++ hw/bsp/mm32/family.mk | 28 ++-- tools/get_deps.py | 2 +- 17 files changed, 495 insertions(+), 725 deletions(-) create mode 100644 hw/bsp/mm32/FreeRTOSConfig/FreeRTOSConfig.h delete mode 100644 hw/bsp/mm32/boards/mm32f327x_bluepillplus/board.mk delete mode 100644 hw/bsp/mm32/boards/mm32f327x_bluepillplus/flash.ld delete mode 100644 hw/bsp/mm32/boards/mm32f327x_bluepillplus/mm32f327x_bluepillplus.c create mode 100644 hw/bsp/mm32/boards/mm32f327x_mb39/board.cmake create mode 100644 hw/bsp/mm32/boards/mm32f327x_mb39/board.h delete mode 100644 hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c create mode 100644 hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.cmake create mode 100644 hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.h delete mode 100644 hw/bsp/mm32/boards/mm32f327x_pitaya_lite/mm32f327x_pitaya_lite.c create mode 100644 hw/bsp/mm32/family.c create mode 100644 hw/bsp/mm32/family.cmake diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 050afe48f..c1f85ad9c 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -45,6 +45,7 @@ jobs: - 'lpc51 lpc54 lpc55' - 'mcx' - 'msp432e4' + - 'mm32' - 'nrf' - 'ra' - 'rp2040' diff --git a/hw/bsp/mm32/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/mm32/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..6622cf801 --- /dev/null +++ b/hw/bsp/mm32/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,150 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "mm32_device.h" + extern u32 SystemCoreClock; +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 0 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 4 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<FLASH - - /* The program code and other data goes into FLASH */ - .text : - { - . = ALIGN(4); - *(.text) /* .text sections (code) */ - *(.text*) /* .text* sections (code) */ - *(.glue_7) /* glue arm to thumb code */ - *(.glue_7t) /* glue thumb to arm code */ - *(.eh_frame) - - KEEP (*(.init)) - KEEP (*(.fini)) - - . = ALIGN(4); - _etext = .; /* define a global symbols at end of code */ - } >FLASH - - /* Constant data goes into FLASH */ - .rodata : - { - . = ALIGN(4); - *(.rodata) /* .rodata sections (constants, strings, etc.) */ - *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ - . = ALIGN(4); - } >FLASH - - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH - .ARM : { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } >FLASH - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array*)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >FLASH - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array*)) - PROVIDE_HIDDEN (__init_array_end = .); - } >FLASH - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT(.fini_array.*))) - KEEP (*(.fini_array*)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >FLASH - - /* used by the startup to initialize data */ - _sidata = LOADADDR(.data); - - /* Initialized data sections goes into RAM, load LMA copy after code */ - .data : - { - . = ALIGN(4); - _sdata = .; /* create a global symbol at data start */ - *(.data) /* .data sections */ - *(.data*) /* .data* sections */ - - . = ALIGN(4); - _edata = .; /* define a global symbol at data end */ - } >RAM AT> FLASH - - - /* Uninitialized data section */ - . = ALIGN(4); - .bss : - { - /* This is used by the startup in order to initialize the .bss section */ - _sbss = .; /* define a global symbol at bss start */ - __bss_start__ = _sbss; - *(.bss) - *(.bss*) - *(COMMON) - - . = ALIGN(4); - _ebss = .; /* define a global symbol at bss end */ - __bss_end__ = _ebss; - } >RAM - - /* User_heap_stack section, used to check that there is enough RAM left */ - ._user_heap_stack : - { - . = ALIGN(8); - PROVIDE ( end = . ); - PROVIDE ( _end = . ); - . = . + _Min_Heap_Size; - . = . + _Min_Stack_Size; - . = ALIGN(8); - } >RAM - - - - /* Remove information from the standard libraries */ - /DISCARD/ : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - - .ARM.attributes 0 : { *(.ARM.attributes) } -} diff --git a/hw/bsp/mm32/boards/mm32f327x_bluepillplus/mm32f327x_bluepillplus.c b/hw/bsp/mm32/boards/mm32f327x_bluepillplus/mm32f327x_bluepillplus.c deleted file mode 100644 index a4bd95fab..000000000 --- a/hw/bsp/mm32/boards/mm32f327x_bluepillplus/mm32f327x_bluepillplus.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 MM32 SE TEAM - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -/* WeAct BluePillPlus with MM32F3273G6P */ - -#include "mm32_device.h" -#include "hal_conf.h" -#include "tusb.h" -#include "bsp/board_api.h" - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void OTG_FS_IRQHandler (void) -{ - tud_int_handler(0); - -} -void USB_DeviceClockInit (void) -{ - /* Select USBCLK source */ - // RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); - RCC->CFGR &= ~(0x3 << 22); - RCC->CFGR |= (0x1 << 22); - - /* Enable USB clock */ - RCC->AHB2ENR |= 0x1 << 7; -} -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ -// LED - -extern u32 SystemCoreClock; -const int baudrate = 115200; - -void board_init (void) -{ -// usb clock - USB_DeviceClockInit(); - - if ( SysTick_Config(SystemCoreClock / 1000) ) - { - while ( 1 ) - ; - } - NVIC_SetPriority(SysTick_IRQn, 0x0); - - // LED on PB2 - GPIO_InitTypeDef GPIO_InitStruct; - RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOB, ENABLE); - GPIO_StructInit(&GPIO_InitStruct); - - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; - GPIO_Init(GPIOB, &GPIO_InitStruct); - - board_led_write(true); - - // KEY on PA0 - RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); - GPIO_StructInit(&GPIO_InitStruct); - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - // UART - UART_InitTypeDef UART_InitStruct; - - RCC_APB2PeriphClockCmd(RCC_APB2ENR_UART1, ENABLE); //enableUART1,GPIOAclock - RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); // - //UART initialset - - GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7); - - UART_StructInit(&UART_InitStruct); - UART_InitStruct.UART_BaudRate = baudrate; - UART_InitStruct.UART_WordLength = UART_WordLength_8b; - UART_InitStruct.UART_StopBits = UART_StopBits_1; //one stopbit - UART_InitStruct.UART_Parity = UART_Parity_No; //none odd-even verify bit - UART_InitStruct.UART_HardwareFlowControl = UART_HardwareFlowControl_None; //No hardware flow control - UART_InitStruct.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; // receive and sent mode - - UART_Init(UART1, &UART_InitStruct); //initial uart 1 - UART_Cmd(UART1, ENABLE); //enable uart 1 - - //UART1_TX GPIOA.9 - GPIO_StructInit(&GPIO_InitStruct); - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - //UART1_RX GPIOA.10 - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; - GPIO_Init(GPIOA, &GPIO_InitStruct); - -} - - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write (bool state) -{ - state ? (GPIO_ResetBits(GPIOB, GPIO_Pin_2)) : (GPIO_SetBits(GPIOB, GPIO_Pin_2)); -} - -uint32_t board_button_read (void) -{ - uint32_t key = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_SET; - return key; -} - -int board_uart_read (uint8_t *buf, int len) -{ - (void) buf; - (void) len; - return 0; -} - -int board_uart_write (void const *buf, int len) -{ - const char *buff = buf; - while ( len ) - { - while ( (UART1->CSR & UART_IT_TXIEN) == 0 ) - ; //The loop is sent until it is finished - UART1->TDR = (*buff & 0xFF); - buff++; - len--; - } - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; -void SysTick_Handler (void) -{ - system_ticks++; -} - -uint32_t board_millis (void) -{ - return system_ticks; -} -#endif - -// Required by __libc_init_array in startup code if we are compiling using -// -nostdlib/-nostartfiles. -void _init(void) -{ - -} diff --git a/hw/bsp/mm32/boards/mm32f327x_mb39/board.cmake b/hw/bsp/mm32/boards/mm32f327x_mb39/board.cmake new file mode 100644 index 000000000..4f3d145cf --- /dev/null +++ b/hw/bsp/mm32/boards/mm32f327x_mb39/board.cmake @@ -0,0 +1,10 @@ +set(MCU_VARIANT mm32f327x) +set(JLINK_DEVICE MM32F3273G9P) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/flash.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + HSE_VALUE=8000000 + ) +endfunction() diff --git a/hw/bsp/mm32/boards/mm32f327x_mb39/board.h b/hw/bsp/mm32/boards/mm32f327x_mb39/board.h new file mode 100644 index 000000000..3ac048cf1 --- /dev/null +++ b/hw/bsp/mm32/boards/mm32f327x_mb39/board.h @@ -0,0 +1,19 @@ +#ifndef BOARD_H +#define BOARD_H + +// GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_15); //Disable JTDI AF to AF15 +#define LED_PORT GPIOA +#define LED_PIN GPIO_Pin_15 +#define LED_STATE_ON 1 + +//#define BUTTON_PORT GPIOC +//#define BUTTON_PIN GPIO_PIN_13 +//#define BUTTON_STATE_ACTIVE 1 + +#define UART_DEV UART1 +#define UART_GPIO_PORT GPIOA +#define UART_GPIO_AF GPIO_AF_7 +#define UART_TX_PIN 9 +#define UART_RX_PIN 10 + +#endif diff --git a/hw/bsp/mm32/boards/mm32f327x_mb39/board.mk b/hw/bsp/mm32/boards/mm32f327x_mb39/board.mk index 803b3adff..f6d18315d 100644 --- a/hw/bsp/mm32/boards/mm32f327x_mb39/board.mk +++ b/hw/bsp/mm32/boards/mm32f327x_mb39/board.mk @@ -1,9 +1,9 @@ +MCU_VARIANT = mm32f327x CFLAGS += \ -DHSE_VALUE=8000000 JLINK_DEVICE = MM32F3273G9P LD_FILE = $(BOARD_PATH)/flash.ld -SRC_S += $(SDK_DIR)/mm32f327x/MM32F327x/Source/GCC_StartAsm/startup_mm32m3ux_u_gcc.S flash: flash-jlink diff --git a/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c b/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c deleted file mode 100644 index 086532179..000000000 --- a/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 MM32 SE TEAM - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "mm32_device.h" -#include "hal_conf.h" -#include "tusb.h" -#include "bsp/board_api.h" - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void OTG_FS_IRQHandler (void) -{ - tud_int_handler(0); - -} -void USB_DeviceClockInit (void) -{ - /* Select USBCLK source */ - // RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); - RCC->CFGR &= ~(0x3 << 22); - RCC->CFGR |= (0x1 << 22); - - /* Enable USB clock */ - RCC->AHB2ENR |= 0x1 << 7; -} -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ -// LED - -extern u32 SystemCoreClock; -const int baudrate = 115200; - -void board_init (void) -{ -// usb clock - USB_DeviceClockInit(); - - if ( SysTick_Config(SystemCoreClock / 1000) ) - { - while ( 1 ) - ; - } - NVIC_SetPriority(SysTick_IRQn, 0x0); - - // LED - GPIO_InitTypeDef GPIO_InitStruct; - RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); - GPIO_StructInit(&GPIO_InitStruct); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_15); //Disable JTDI AF to AF15 - - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - board_led_write(true); - - // UART - UART_InitTypeDef UART_InitStruct; - - RCC_APB2PeriphClockCmd(RCC_APB2ENR_UART1, ENABLE); //enableUART1,GPIOAclock - RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); // - //UART initialset - - GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7); - - UART_StructInit(&UART_InitStruct); - UART_InitStruct.UART_BaudRate = baudrate; - UART_InitStruct.UART_WordLength = UART_WordLength_8b; - UART_InitStruct.UART_StopBits = UART_StopBits_1; //one stopbit - UART_InitStruct.UART_Parity = UART_Parity_No; //none odd-even verify bit - UART_InitStruct.UART_HardwareFlowControl = UART_HardwareFlowControl_None; //No hardware flow control - UART_InitStruct.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; // receive and sent mode - - UART_Init(UART1, &UART_InitStruct); //initial uart 1 - UART_Cmd(UART1, ENABLE); //enable uart 1 - - //UART1_TX GPIOA.9 - GPIO_StructInit(&GPIO_InitStruct); - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - //UART1_RX GPIOA.10 - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; - GPIO_Init(GPIOA, &GPIO_InitStruct); - -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write (bool state) -{ - state ? (GPIO_ResetBits(GPIOA, GPIO_Pin_15)) : (GPIO_SetBits(GPIOA, GPIO_Pin_15)); -} - -uint32_t board_button_read (void) -{ - return 0; -} - -int board_uart_read (uint8_t *buf, int len) -{ - (void) buf; - (void) len; - return 0; -} - -int board_uart_write (void const *buf, int len) -{ - const char *buff = buf; - while ( len ) - { - while ( (UART1->CSR & UART_IT_TXIEN) == 0 ) - ; //The loop is sent until it is finished - UART1->TDR = (*buff & 0xFF); - buff++; - len--; - } - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; -void SysTick_Handler (void) -{ - system_ticks++; -} - -uint32_t board_millis (void) -{ - return system_ticks; -} -#endif - -// Required by __libc_init_array in startup code if we are compiling using -// -nostdlib/-nostartfiles. -void _init(void) -{ - -} diff --git a/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.cmake b/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.cmake new file mode 100644 index 000000000..4de25e2c4 --- /dev/null +++ b/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.cmake @@ -0,0 +1,10 @@ +set(MCU_VARIANT mm32f327x) +set(JLINK_DEVICE MM32F3273G8P) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/flash.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + HSE_VALUE=12000000 + ) +endfunction() diff --git a/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.h b/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.h new file mode 100644 index 000000000..9ace1d357 --- /dev/null +++ b/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.h @@ -0,0 +1,14 @@ +#ifndef BOARD_H +#define BOARD_H + +// GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_15); //Disable JTDI AF to AF15 +#define LED_PORT GPIOA +#define LED_PIN GPIO_Pin_1 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 0 + + +#endif diff --git a/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.mk b/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.mk index a778e749f..dbcd314c8 100644 --- a/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.mk +++ b/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.mk @@ -1,11 +1,12 @@ +MCU_VARIANT = mm32f327x + CFLAGS += \ -DHSE_VALUE=12000000 LD_FILE = $(BOARD_PATH)/flash.ld -SRC_S += $(SDK_DIR)/mm32f327x/MM32F327x/Source/GCC_StartAsm/startup_mm32m3ux_u_gcc.S # For flash-jlink target -#JLINK_DEVICE = MM32F3273G8P +JLINK_DEVICE = MM32F3273G8P # flash target using on-board stlink #flash: flash-jlink diff --git a/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/mm32f327x_pitaya_lite.c b/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/mm32f327x_pitaya_lite.c deleted file mode 100644 index bd2d36ae0..000000000 --- a/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/mm32f327x_pitaya_lite.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 MM32 SE TEAM - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -/* DshanMCU Pitaya Lite with MM32F3273 */ - -#include "mm32_device.h" -#include "hal_conf.h" -#include "tusb.h" -#include "bsp/board_api.h" - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void OTG_FS_IRQHandler (void) -{ - tud_int_handler(0); - -} -void USB_DeviceClockInit (void) -{ - /* Select USBCLK source */ - // RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); - RCC->CFGR &= ~(0x3 << 22); - RCC->CFGR |= (0x1 << 22); - - /* Enable USB clock */ - RCC->AHB2ENR |= 0x1 << 7; -} -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ -// LED - -extern u32 SystemCoreClock; -const int baudrate = 115200; - -void board_init (void) -{ -// usb clock -// requires SYSCLK_FREQ_XXMHz (HSE_VALUE*8) in system_mm32f327x.c - USB_DeviceClockInit(); - - if ( SysTick_Config(SystemCoreClock / 1000) ) - { - while ( 1 ) - ; - } - NVIC_SetPriority(SysTick_IRQn, 0x0); - - // LED on PA1 - GPIO_InitTypeDef GPIO_InitStruct; - RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); - GPIO_StructInit(&GPIO_InitStruct); - - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - board_led_write(true); - - // KEY on PA0 - GPIO_StructInit(&GPIO_InitStruct); - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_FLOATING; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - // UART - UART_InitTypeDef UART_InitStruct; - - RCC_APB2PeriphClockCmd(RCC_APB2ENR_UART1, ENABLE); //enableUART1,GPIOAclock - RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); // - //UART initialset - - GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7); - - UART_StructInit(&UART_InitStruct); - UART_InitStruct.UART_BaudRate = baudrate; - UART_InitStruct.UART_WordLength = UART_WordLength_8b; - UART_InitStruct.UART_StopBits = UART_StopBits_1; //one stopbit - UART_InitStruct.UART_Parity = UART_Parity_No; //none odd-even verify bit - UART_InitStruct.UART_HardwareFlowControl = UART_HardwareFlowControl_None; //No hardware flow control - UART_InitStruct.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; // receive and sent mode - - UART_Init(UART1, &UART_InitStruct); //initial uart 1 - UART_Cmd(UART1, ENABLE); //enable uart 1 - - //UART1_TX GPIOA.9 - GPIO_StructInit(&GPIO_InitStruct); - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - //UART1_RX GPIOA.10 - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; - GPIO_Init(GPIOA, &GPIO_InitStruct); - -} - - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write (bool state) -{ - state ? (GPIO_ResetBits(GPIOA, GPIO_Pin_1)) : (GPIO_SetBits(GPIOA, GPIO_Pin_1)); -} - -uint32_t board_button_read (void) -{ - uint32_t key = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_RESET; - return key; -} - -int board_uart_read (uint8_t *buf, int len) -{ - (void) buf; - (void) len; - return 0; -} - -int board_uart_write (void const *buf, int len) -{ - const char *buff = buf; - while ( len ) - { - while ( (UART1->CSR & UART_IT_TXIEN) == 0 ) - ; //The loop is sent until it is finished - UART1->TDR = (*buff & 0xFF); - buff++; - len--; - } - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; -void SysTick_Handler (void) -{ - system_ticks++; -} - -uint32_t board_millis (void) -{ - return system_ticks; -} -#endif - -// Required by __libc_init_array in startup code if we are compiling using -// -nostdlib/-nostartfiles. -void _init(void) -{ - -} diff --git a/hw/bsp/mm32/family.c b/hw/bsp/mm32/family.c new file mode 100644 index 000000000..f22fd90a1 --- /dev/null +++ b/hw/bsp/mm32/family.c @@ -0,0 +1,169 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 MM32 SE TEAM + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "hal_conf.h" +#include "mm32_device.h" + +#include "bsp/board_api.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void OTG_FS_IRQHandler(void) { + tud_int_handler(0); +} + +void USB_DeviceClockInit(void) { + /* Select USBCLK source */ + // RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); + RCC->CFGR &= ~(0x3 << 22); + RCC->CFGR |= (0x1 << 22); + + /* Enable USB clock */ + RCC->AHB2ENR |= 0x1 << 7; +} +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +extern u32 SystemCoreClock; + +void board_init(void) { +// usb clock + USB_DeviceClockInit(); + + if (SysTick_Config(SystemCoreClock / 1000)) { + while (1); + } + NVIC_SetPriority(SysTick_IRQn, 0x0); + + RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); + + // LED + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_StructInit(&GPIO_InitStruct); + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15; + GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + board_led_write(true); + + #ifdef BUTTON_PORT + GPIO_StructInit(&GPIO_InitStruct); + GPIO_InitStruct.GPIO_Pin = BUTTON_PIN; + GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz; + GPIO_InitStruct.GPIO_Mode = BUTTON_STATE_ACTIVE ? GPIO_Mode_IPD : GPIO_Mode_IPU; + GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + #endif + + #ifdef UART_DEV + // UART + UART_InitTypeDef UART_InitStruct; + + RCC_APB2PeriphClockCmd(RCC_APB2ENR_UART1, ENABLE); //enableUART1,GPIOAclock + GPIO_PinAFConfig(GPIOA, UART_TX_PIN, UART_GPIO_AF); + GPIO_PinAFConfig(GPIOA, UART_RX_PIN, UART_GPIO_AF); + + UART_StructInit(&UART_InitStruct); + UART_InitStruct.UART_BaudRate = CFG_BOARD_UART_BAUDRATE; + UART_InitStruct.UART_WordLength = UART_WordLength_8b; + UART_InitStruct.UART_StopBits = UART_StopBits_1; + UART_InitStruct.UART_Parity = UART_Parity_No; + UART_InitStruct.UART_HardwareFlowControl = UART_HardwareFlowControl_None; + UART_InitStruct.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; + + UART_Init(UART_DEV, &UART_InitStruct); + UART_Cmd(UART_DEV, ENABLE); + + GPIO_StructInit(&GPIO_InitStruct); + GPIO_InitStruct.GPIO_Pin = 1 << UART_TX_PIN; + GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + + GPIO_InitStruct.GPIO_Pin = 1 << UART_RX_PIN; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; + GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + #endif +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { + GPIO_WriteBit(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); +} + +uint32_t board_button_read(void) { +#ifdef BUTTON_PORT + return GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN) == BUTTON_STATE_ACTIVE; +#else + return 0; +#endif +} + +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const* buf, int len) { + #ifdef UART_DEV + const char* buff = buf; + while (len) { + while ((UART1->CSR & UART_IT_TXIEN) == 0); //The loop is sent until it is finished + UART1->TDR = (*buff & 0xFF); + buff++; + len--; + } + return len; + #else + (void) buf; + (void) len; + return 0; + #endif +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; +} + +uint32_t board_millis(void) { + return system_ticks; +} +#endif + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) { +} diff --git a/hw/bsp/mm32/family.cmake b/hw/bsp/mm32/family.cmake new file mode 100644 index 000000000..bf315acaa --- /dev/null +++ b/hw/bsp/mm32/family.cmake @@ -0,0 +1,101 @@ +include_guard() + +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +string(REPLACE "mm32f" "MM32F" MCU_VARIANT_UPPER ${MCU_VARIANT}) +set(SDK_DIR ${TOP}/hw/mcu/mindmotion/mm32sdk/${MCU_VARIANT_UPPER}) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m3 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS MM32F327X CACHE INTERNAL "") + + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + # Startup & Linker script + set(STARTUP_FILE_GNU ${SDK_DIR}/Source/GCC_StartAsm/startup_${MCU_VARIANT}_gcc.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${SDK_DIR}/Source/IAR_StartAsm/startup_${MCU_VARIANT}_iar.s) + + set(LD_FILE_Clang ${LD_FILE_GNU}) + # set(LD_FILE_IAR ) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/Source/system_${MCU_VARIANT}.c + ${SDK_DIR}/HAL_Lib/Src/hal_gpio.c + ${SDK_DIR}/HAL_Lib/Src/hal_rcc.c + ${SDK_DIR}/HAL_Lib/Src/hal_uart.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMSIS_5}/CMSIS/Core/Include + ${SDK_DIR}/Include + ${SDK_DIR}/HAL_Lib/Inc + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_MM32F327X ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/mm32/family.mk b/hw/bsp/mm32/family.mk index 2e8e595b9..a790663ab 100644 --- a/hw/bsp/mm32/family.mk +++ b/hw/bsp/mm32/family.mk @@ -1,29 +1,33 @@ UF2_FAMILY_ID = 0x0 -SDK_DIR = hw/mcu/mindmotion/mm32sdk -DEPS_SUBMODULES += lib/CMSIS_5 $(SDK_DIR) - include $(TOP)/$(BOARD_PATH)/board.mk + +MCU_VARIANT_UPPER = $(subst mm32f,MM32F,${MCU_VARIANT}) +SDK_DIR = hw/mcu/mindmotion/mm32sdk/${MCU_VARIANT_UPPER} + CPU_CORE ?= cortex-m3 CFLAGS += \ -flto \ - -nostdlib -nostartfiles \ - -DCFG_TUSB_MCU=OPT_MCU_MM32F327X + -DCFG_TUSB_MCU=OPT_MCU_MM32F327X \ # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=unused-parameter -Wno-error=maybe-uninitialized -Wno-error=cast-qual -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + -specs=nosys.specs -specs=nano.specs \ SRC_C += \ src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c \ - $(SDK_DIR)/mm32f327x/MM32F327x/Source/system_mm32f327x.c \ - $(SDK_DIR)/mm32f327x/MM32F327x/HAL_Lib/Src/hal_gpio.c \ - $(SDK_DIR)/mm32f327x/MM32F327x/HAL_Lib/Src/hal_rcc.c \ - $(SDK_DIR)/mm32f327x/MM32F327x/HAL_Lib/Src/hal_uart.c \ + $(SDK_DIR)/Source/system_${MCU_VARIANT}.c \ + $(SDK_DIR)/HAL_Lib/Src/hal_gpio.c \ + $(SDK_DIR)/HAL_Lib/Src/hal_rcc.c \ + $(SDK_DIR)/HAL_Lib/Src/hal_uart.c \ + +SRC_S += ${SDK_DIR}/Source/GCC_StartAsm/startup_${MCU_VARIANT}_gcc.s INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ - $(TOP)/$(SDK_DIR)/mm32f327x/MM32F327x/Include \ - $(TOP)/$(SDK_DIR)/mm32f327x/MM32F327x/HAL_Lib/Inc + $(TOP)/$(SDK_DIR)/Include \ + $(TOP)/$(SDK_DIR)/HAL_Lib/Inc diff --git a/tools/get_deps.py b/tools/get_deps.py index 75dd283ea..cdb5dafe1 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -39,7 +39,7 @@ deps_optional = { '9e8b37e307d8404033bb881623a113931e1edf27', 'sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg'], 'hw/mcu/mindmotion/mm32sdk': ['https://github.com/hathach/mm32sdk.git', - '0b79559eb411149d36e073c1635c620e576308d4', + 'b93e856211060ae825216c6a1d6aa347ec758843', 'mm32'], 'hw/mcu/nordic/nrfx': ['https://github.com/NordicSemiconductor/nrfx.git', '7c47cc0a56ce44658e6da2458e86cd8783ccc4a2', -- cgit v1.3.1 From a9f1c62dffc2cb0229767959173f78eec9931db0 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 May 2024 17:28:48 +0700 Subject: temp fix for mm32 redundant-decls of SystemCoreClock --- hw/bsp/mm32/family.c | 24 ++++++++++++++++-------- src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c | 11 +++++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/hw/bsp/mm32/family.c b/hw/bsp/mm32/family.c index f22fd90a1..f0fd6d334 100644 --- a/hw/bsp/mm32/family.c +++ b/hw/bsp/mm32/family.c @@ -30,6 +30,21 @@ #include "bsp/board_api.h" #include "board.h" +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +#ifdef __GNUC__ // caused by extra declaration of SystemCoreClock in freeRTOSConfig.h +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif + +extern u32 SystemCoreClock; + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ @@ -46,19 +61,12 @@ void USB_DeviceClockInit(void) { /* Enable USB clock */ RCC->AHB2ENR |= 0x1 << 7; } -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ - -extern u32 SystemCoreClock; void board_init(void) { // usb clock USB_DeviceClockInit(); - if (SysTick_Config(SystemCoreClock / 1000)) { - while (1); - } + SysTick_Config(SystemCoreClock / 1000); NVIC_SetPriority(SysTick_IRQn, 0x0); RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); diff --git a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c index c3d0c7297..d5c0daaeb 100644 --- a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c +++ b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c @@ -283,7 +283,18 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) /* Response with status first before changing device address */ dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); } + +#ifdef __GNUC__ // caused by extra declaration of SystemCoreClock in freeRTOSConfig.h +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif + extern u32 SystemCoreClock; + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; -- cgit v1.3.1 From dfda0b124f4e436e81770cb4986523da1036f654 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 May 2024 17:31:00 +0700 Subject: fix typo --- hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.h b/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.h index 9ace1d357..2b3f54a60 100644 --- a/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.h +++ b/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.h @@ -7,7 +7,7 @@ #define LED_STATE_ON 1 #define BUTTON_PORT GPIOA -#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_PIN GPIO_Pin_0 #define BUTTON_STATE_ACTIVE 0 -- cgit v1.3.1 From 91d69fa942c8a450c9816595f0d19138964533ef Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 7 May 2024 00:10:26 +0200 Subject: Reformat NCM class. --- src/class/net/ncm.h | 141 +++-- src/class/net/ncm_device.c | 1270 ++++++++++++++++++++------------------------ 2 files changed, 640 insertions(+), 771 deletions(-) diff --git a/src/class/net/ncm.h b/src/class/net/ncm.h index cf4daf96c..1b987fca0 100644 --- a/src/class/net/ncm.h +++ b/src/class/net/ncm.h @@ -25,58 +25,59 @@ * This file is part of the TinyUSB stack. */ - #ifndef _TUSB_NCM_H_ #define _TUSB_NCM_H_ #include "common/tusb_common.h" -#include "lwipopts.h" -#ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE - #define CFG_TUD_NCM_IN_NTB_MAX_SIZE (2 * TCP_MSS + 100) -#endif +// NTB buffers size for reception side, must be >> MTU to avoid TCP retransmission (driver issue ?) +// Linux use 2048 as minimal size #ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE - #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE (2 * TCP_MSS + 100) + #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE 3200 +#endif + +// NTB buffers size for reception side, must be > MTU +// Linux use 2048 as minimal size +#ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE + #define CFG_TUD_NCM_IN_NTB_MAX_SIZE 3200 #endif +// Number of NTB buffers for reception side +// Depending on the configuration, this parameter could be increased with the cost of additional RAM requirements +// On Full-Speed (RP2040) : +// 1 - good performance +// 2 - up to 30% more performance with iperf with small packets +// >2 - no performance gain +// On High-Speed (STM32F7) : +// No performance gain #ifndef CFG_TUD_NCM_OUT_NTB_N - /// number of NTB buffers for reception side - /// 1 - good performance - /// 2 - up to 30% more performance with iperf with small packets - /// >2 - no performance gain - /// -> for performance optimizations this parameter could be increased with the cost of additional RAM requirements - #define CFG_TUD_NCM_OUT_NTB_N 1 + #define CFG_TUD_NCM_OUT_NTB_N 1 #endif +// Number of NTB buffers for transmission side +// Depending on the configuration, this parameter could be increased with the cost of additional RAM requirements +// On Full-Speed (RP2040) : +// 1 - good performance but SystemView shows lost events (on load test) +// 2 - up to 50% more performance with iperf with small packets, "tud_network_can_xmit: request blocked" +// happens from time to time with SystemView +// 3 - "tud_network_can_xmit: request blocked" never happens +// >3 - no performance gain +// On High-Speed (STM32F7) : +// No performance gain #ifndef CFG_TUD_NCM_IN_NTB_N - /// number of NTB buffers for transmission side - /// 1 - good performance but SystemView shows lost events (on load test) - /// 2 - up to 50% more performance with iperf with small packets, "tud_network_can_xmit: request blocked" - /// happens from time to time with SystemView - /// 3 - "tud_network_can_xmit: request blocked" never happens - /// >2 - no performance gain - /// -> for performance optimizations this parameter could be increased with the cost of additional RAM requirements - #define CFG_TUD_NCM_IN_NTB_N 1 + #define CFG_TUD_NCM_IN_NTB_N 1 #endif +// How many datagrams it is allowed to put into an NTB for transmission side #ifndef CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB - /// this is for the transmission side for allocation of \a ndp16_datagram_t - #define CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB 8 + #define CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB 8 #endif +// This tells the host how many datagrams it is allowed to put into an NTB #ifndef CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB - /// this tells the host how many datagrams it is allowed to put into an NTB - #define CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB 6 + #define CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB 6 #endif -#ifndef CFG_TUD_NCM_ALIGNMENT - #define CFG_TUD_NCM_ALIGNMENT 4 -#endif -#if (CFG_TUD_NCM_ALIGNMENT != 4) - #error "CFG_TUD_NCM_ALIGNMENT must be 4, otherwise the headers and start of datagrams have to be aligned (which they are currently not)" -#endif - - // Table 6.2 Class-Specific Request Codes for Network Control Model subclass typedef enum { @@ -98,67 +99,65 @@ typedef enum NCM_SET_CRC_MODE = 0x8A, } ncm_request_code_t; - -#define NTH16_SIGNATURE 0x484D434E +#define NTH16_SIGNATURE 0x484D434E #define NDP16_SIGNATURE_NCM0 0x304D434E #define NDP16_SIGNATURE_NCM1 0x314D434E typedef struct TU_ATTR_PACKED { - uint16_t wLength; - uint16_t bmNtbFormatsSupported; - uint32_t dwNtbInMaxSize; - uint16_t wNdbInDivisor; - uint16_t wNdbInPayloadRemainder; - uint16_t wNdbInAlignment; - uint16_t wReserved; - uint32_t dwNtbOutMaxSize; - uint16_t wNdbOutDivisor; - uint16_t wNdbOutPayloadRemainder; - uint16_t wNdbOutAlignment; - uint16_t wNtbOutMaxDatagrams; + uint16_t wLength; + uint16_t bmNtbFormatsSupported; + uint32_t dwNtbInMaxSize; + uint16_t wNdbInDivisor; + uint16_t wNdbInPayloadRemainder; + uint16_t wNdbInAlignment; + uint16_t wReserved; + uint32_t dwNtbOutMaxSize; + uint16_t wNdbOutDivisor; + uint16_t wNdbOutPayloadRemainder; + uint16_t wNdbOutAlignment; + uint16_t wNtbOutMaxDatagrams; } ntb_parameters_t; typedef struct TU_ATTR_PACKED { - uint32_t dwSignature; - uint16_t wHeaderLength; - uint16_t wSequence; - uint16_t wBlockLength; - uint16_t wNdpIndex; + uint32_t dwSignature; + uint16_t wHeaderLength; + uint16_t wSequence; + uint16_t wBlockLength; + uint16_t wNdpIndex; } nth16_t; typedef struct TU_ATTR_PACKED { - uint16_t wDatagramIndex; - uint16_t wDatagramLength; + uint16_t wDatagramIndex; + uint16_t wDatagramLength; } ndp16_datagram_t; typedef struct TU_ATTR_PACKED { - uint32_t dwSignature; - uint16_t wLength; - uint16_t wNextNdpIndex; - //ndp16_datagram_t datagram[]; + uint32_t dwSignature; + uint16_t wLength; + uint16_t wNextNdpIndex; + //ndp16_datagram_t datagram[]; } ndp16_t; typedef union TU_ATTR_PACKED { - struct { - nth16_t nth; - ndp16_t ndp; - ndp16_datagram_t ndp_datagram[CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB + 1]; - }; - uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; + struct { + nth16_t nth; + ndp16_t ndp; + ndp16_datagram_t ndp_datagram[CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB + 1]; + }; + uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; } xmit_ntb_t; typedef union TU_ATTR_PACKED { - struct { - nth16_t nth; - // only the header is at a guaranteed position - }; - uint8_t data[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; + struct { + nth16_t nth; + // only the header is at a guaranteed position + }; + uint8_t data[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; } recv_ntb_t; struct ncm_notify_t { - tusb_control_request_t header; - uint32_t downlink, uplink; + tusb_control_request_t header; + uint32_t downlink, uplink; }; - #endif diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 05cebf94e..4b237e4cf 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -46,7 +46,7 @@ #include "tusb_option.h" -#if defined(ECLIPSE_GUI) || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) +#if (CFG_TUD_ENABLED && CFG_TUD_NCM) #include #include @@ -55,59 +55,65 @@ #include "device/usbd.h" #include "device/usbd_pvt.h" -#include "net_device.h" #include "ncm.h" +#include "net_device.h" + +// Level where CFG_TUSB_DEBUG must be at least for this driver is logged +#ifndef CFG_TUD_NCM_LOG_LEVEL + #define CFG_TUD_NCM_LOG_LEVEL CFG_TUD_LOG_LEVEL +#endif +#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_NCM_LOG_LEVEL, __VA_ARGS__) +// Alignment must be 4 +#define TUD_NCM_ALIGNMENT 4 // calculate alignment of xmit datagrams within an NTB -#define XMIT_ALIGN_OFFSET(x) ((CFG_TUD_NCM_ALIGNMENT - ((x) & (CFG_TUD_NCM_ALIGNMENT - 1))) & (CFG_TUD_NCM_ALIGNMENT - 1)) +#define XMIT_ALIGN_OFFSET(x) ((TUD_NCM_ALIGNMENT - ((x) & (TUD_NCM_ALIGNMENT - 1))) & (TUD_NCM_ALIGNMENT - 1)) //----------------------------------------------------------------------------- // // Module global things // -#define XMIT_NTB_N CFG_TUD_NCM_IN_NTB_N -#define RECV_NTB_N CFG_TUD_NCM_OUT_NTB_N +#define XMIT_NTB_N CFG_TUD_NCM_IN_NTB_N +#define RECV_NTB_N CFG_TUD_NCM_OUT_NTB_N typedef struct { - // general - uint8_t ep_in; //!< endpoint for outgoing datagrams (naming is a little bit confusing) - uint8_t ep_out; //!< endpoint for incoming datagrams (naming is a little bit confusing) - uint8_t ep_notif; //!< endpoint for notifications - uint8_t itf_num; //!< interface number - uint8_t itf_data_alt; //!< ==0 -> no endpoints, i.e. no network traffic, ==1 -> normal operation with two endpoints (spec, chapter 5.3) - uint8_t rhport; //!< storage of \a rhport because some callbacks are done without it - - // recv handling - CFG_TUSB_MEM_ALIGN recv_ntb_t recv_ntb[RECV_NTB_N]; //!< actual recv NTBs - recv_ntb_t *recv_free_ntb[RECV_NTB_N]; //!< free list of recv NTBs - recv_ntb_t *recv_ready_ntb[RECV_NTB_N]; //!< NTBs waiting for transmission to glue logic - recv_ntb_t *recv_tinyusb_ntb; //!< buffer for the running transfer TinyUSB -> driver - recv_ntb_t *recv_glue_ntb; //!< buffer for the running transfer driver -> glue logic - uint16_t recv_glue_ntb_datagram_ndx; //!< index into \a recv_glue_ntb_datagram - - // xmit handling - CFG_TUSB_MEM_ALIGN xmit_ntb_t xmit_ntb[XMIT_NTB_N]; //!< actual xmit NTBs - xmit_ntb_t *xmit_free_ntb[XMIT_NTB_N]; //!< free list of xmit NTBs - xmit_ntb_t *xmit_ready_ntb[XMIT_NTB_N]; //!< NTBs waiting for transmission to TinyUSB - xmit_ntb_t *xmit_tinyusb_ntb; //!< buffer for the running transfer driver -> TinyUSB - xmit_ntb_t *xmit_glue_ntb; //!< buffer for the running transfer glue logic -> driver - uint16_t xmit_sequence; //!< NTB sequence counter - uint16_t xmit_glue_ntb_datagram_ndx; //!< index into \a xmit_glue_ntb_datagram - - // notification handling - enum { - NOTIFICATION_SPEED, - NOTIFICATION_CONNECTED, - NOTIFICATION_DONE - } notification_xmit_state; //!< state of notification transmission - bool notification_xmit_is_running; //!< notification is currently transmitted + // general + uint8_t ep_in; // endpoint for outgoing datagrams (naming is a little bit confusing) + uint8_t ep_out; // endpoint for incoming datagrams (naming is a little bit confusing) + uint8_t ep_notif; // endpoint for notifications + uint8_t itf_num; // interface number + uint8_t itf_data_alt; // ==0 -> no endpoints, i.e. no network traffic, ==1 -> normal operation with two endpoints (spec, chapter 5.3) + uint8_t rhport; // storage of \a rhport because some callbacks are done without it + + // recv handling + CFG_TUSB_MEM_ALIGN recv_ntb_t recv_ntb[RECV_NTB_N]; // actual recv NTBs + recv_ntb_t *recv_free_ntb[RECV_NTB_N]; // free list of recv NTBs + recv_ntb_t *recv_ready_ntb[RECV_NTB_N]; // NTBs waiting for transmission to glue logic + recv_ntb_t *recv_tinyusb_ntb; // buffer for the running transfer TinyUSB -> driver + recv_ntb_t *recv_glue_ntb; // buffer for the running transfer driver -> glue logic + uint16_t recv_glue_ntb_datagram_ndx; // index into \a recv_glue_ntb_datagram + + // xmit handling + CFG_TUSB_MEM_ALIGN xmit_ntb_t xmit_ntb[XMIT_NTB_N]; // actual xmit NTBs + xmit_ntb_t *xmit_free_ntb[XMIT_NTB_N]; // free list of xmit NTBs + xmit_ntb_t *xmit_ready_ntb[XMIT_NTB_N]; // NTBs waiting for transmission to TinyUSB + xmit_ntb_t *xmit_tinyusb_ntb; // buffer for the running transfer driver -> TinyUSB + xmit_ntb_t *xmit_glue_ntb; // buffer for the running transfer glue logic -> driver + uint16_t xmit_sequence; // NTB sequence counter + uint16_t xmit_glue_ntb_datagram_ndx; // index into \a xmit_glue_ntb_datagram + + // notification handling + enum { + NOTIFICATION_SPEED, + NOTIFICATION_CONNECTED, + NOTIFICATION_DONE + } notification_xmit_state; // state of notification transmission + bool notification_xmit_is_running; // notification is currently transmitted } ncm_interface_t; - CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static ncm_interface_t ncm_interface; - /** * This is the NTB parameter structure * @@ -115,18 +121,18 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static ncm_interface_t ncm_interface; * We are lucky, that byte order is correct */ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { - .wLength = sizeof(ntb_parameters_t), - .bmNtbFormatsSupported = 0x01, // 16-bit NTB supported - .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, - .wNdbInDivisor = 4, - .wNdbInPayloadRemainder = 0, - .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, - .wReserved = 0, - .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, - .wNdbOutDivisor = 4, - .wNdbOutPayloadRemainder = 0, - .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, - .wNtbOutMaxDatagrams = CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB, + .wLength = sizeof(ntb_parameters_t), + .bmNtbFormatsSupported = 0x01,// 16-bit NTB supported + .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, + .wNdbInDivisor = 1, + .wNdbInPayloadRemainder = 0, + .wNdbInAlignment = TUD_NCM_ALIGNMENT, + .wReserved = 0, + .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, + .wNdbOutDivisor = 1, + .wNdbOutPayloadRemainder = 0, + .wNdbOutAlignment = TUD_NCM_ALIGNMENT, + .wNtbOutMaxDatagrams = CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB, }; // Some confusing remarks about wNtbOutMaxDatagrams... @@ -135,7 +141,6 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par // ==6 -> SystemView runs fine, iperf also // >6 -> iperf starts to show errors // -> 6 seems to be the best value. Why? Don't know, perhaps only on my system? -// switch \a TU_LOG2 on to see interesting values for this. // // iperf: for MSS in 100 200 400 800 1200 1450 1500; do iperf -c 192.168.14.1 -e -i 1 -M $MSS -l 8192 -P 1; sleep 2; done // sysview: SYSTICKS_PER_SEC=35000, IDLE_US=1000, PRINT_MOD=1000 @@ -146,151 +151,128 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par // everything about notifications // tu_static struct ncm_notify_t ncm_notify_connected = { - .header = { - .bmRequestType_bit = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, - .bRequest = CDC_NOTIF_NETWORK_CONNECTION, - .wValue = 1 /* Connected */, - .wLength = 0, - }, + .header = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN}, + .bRequest = CDC_NOTIF_NETWORK_CONNECTION, + .wValue = 1 /* Connected */, + .wLength = 0, + }, }; tu_static struct ncm_notify_t ncm_notify_speed_change = { - .header = { - .bmRequestType_bit = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, - .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE, - .wLength = 8, - }, - .downlink = 12000000, - .uplink = 12000000, + .header = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN}, + .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE, + .wLength = 8, + }, + .downlink = TUD_OPT_HIGH_SPEED ? 480000000 : 12000000, + .uplink = TUD_OPT_HIGH_SPEED ? 480000000 : 12000000, }; - - -static void notification_xmit(uint8_t rhport, bool force_next) /** * Transmit next notification to the host (if appropriate). * Notifications are transferred to the host once during connection setup. */ -{ - TU_LOG3("notification_xmit(%d, %d) - %d %d\n", force_next, rhport, ncm_interface.notification_xmit_state, ncm_interface.notification_xmit_is_running); - - if ( !force_next && ncm_interface.notification_xmit_is_running) { - return; - } - - if (ncm_interface.notification_xmit_state == NOTIFICATION_SPEED) { - TU_LOG3(" NOTIFICATION_SPEED\n"); - ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; - usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*) &ncm_notify_speed_change, sizeof(ncm_notify_speed_change)); - ncm_interface.notification_xmit_state = NOTIFICATION_CONNECTED; - ncm_interface.notification_xmit_is_running = true; - } - else if (ncm_interface.notification_xmit_state == NOTIFICATION_CONNECTED) { - TU_LOG3(" NOTIFICATION_CONNECTED\n"); - ncm_notify_connected.header.wIndex = ncm_interface.itf_num; - usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*) &ncm_notify_connected, sizeof(ncm_notify_connected)); - ncm_interface.notification_xmit_state = NOTIFICATION_DONE; - ncm_interface.notification_xmit_is_running = true; - } - else { - TU_LOG3(" NOTIFICATION_FINISHED\n"); - } -} // notification_xmit - +static void notification_xmit(uint8_t rhport, bool force_next) { + TU_LOG_DRV("notification_xmit(%d, %d) - %d %d\n", force_next, rhport, ncm_interface.notification_xmit_state, ncm_interface.notification_xmit_is_running); + + if (!force_next && ncm_interface.notification_xmit_is_running) { + return; + } + + if (ncm_interface.notification_xmit_state == NOTIFICATION_SPEED) { + TU_LOG_DRV(" NOTIFICATION_SPEED\n"); + ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_speed_change, sizeof(ncm_notify_speed_change)); + ncm_interface.notification_xmit_state = NOTIFICATION_CONNECTED; + ncm_interface.notification_xmit_is_running = true; + } else if (ncm_interface.notification_xmit_state == NOTIFICATION_CONNECTED) { + TU_LOG_DRV(" NOTIFICATION_CONNECTED\n"); + ncm_notify_connected.header.wIndex = ncm_interface.itf_num; + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_connected, sizeof(ncm_notify_connected)); + ncm_interface.notification_xmit_state = NOTIFICATION_DONE; + ncm_interface.notification_xmit_is_running = true; + } else { + TU_LOG_DRV(" NOTIFICATION_FINISHED\n"); + } +} // notification_xmit //----------------------------------------------------------------------------- // // everything about packet transmission (driver -> TinyUSB) // - -static void xmit_put_ntb_into_free_list(xmit_ntb_t *free_ntb) /** * Put NTB into the transmitter free list. */ -{ - TU_LOG3("xmit_put_ntb_into_free_list() - %p\n", ncm_interface.xmit_tinyusb_ntb); +static void xmit_put_ntb_into_free_list(xmit_ntb_t *free_ntb) { + TU_LOG_DRV("xmit_put_ntb_into_free_list() - %p\n", ncm_interface.xmit_tinyusb_ntb); - if (free_ntb == NULL) { - // can happen due to ZLPs - return; - } + if (free_ntb == NULL) { // can happen due to ZLPs + return; + } - for (int i = 0; i < XMIT_NTB_N; ++i) { - if (ncm_interface.xmit_free_ntb[i] == NULL) { - ncm_interface.xmit_free_ntb[i] = free_ntb; - return; - } + for (int i = 0; i < XMIT_NTB_N; ++i) { + if (ncm_interface.xmit_free_ntb[i] == NULL) { + ncm_interface.xmit_free_ntb[i] = free_ntb; + return; } - TU_LOG1("(EE) xmit_put_ntb_into_free_list - no entry in free list\n"); // this should not happen -} // xmit_put_ntb_into_free_list - - + } + TU_LOG_DRV("(EE) xmit_put_ntb_into_free_list - no entry in free list\n");// this should not happen +} // xmit_put_ntb_into_free_list -static xmit_ntb_t *xmit_get_free_ntb(void) /** * Get an NTB from the free list */ -{ - TU_LOG3("xmit_get_free_ntb()\n"); - - for (int i = 0; i < XMIT_NTB_N; ++i) { - if (ncm_interface.xmit_free_ntb[i] != NULL) { - xmit_ntb_t *free = ncm_interface.xmit_free_ntb[i]; - ncm_interface.xmit_free_ntb[i] = NULL; - return free; - } - } - return NULL; -} // xmit_get_free_ntb - +static xmit_ntb_t *xmit_get_free_ntb(void) { + TU_LOG_DRV("xmit_get_free_ntb()\n"); + for (int i = 0; i < XMIT_NTB_N; ++i) { + if (ncm_interface.xmit_free_ntb[i] != NULL) { + xmit_ntb_t *free = ncm_interface.xmit_free_ntb[i]; + ncm_interface.xmit_free_ntb[i] = NULL; + return free; + } + } + return NULL; +} // xmit_get_free_ntb -static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) /** * Put a filled NTB into the ready list */ -{ - TU_LOG2("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); +static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) { + TU_LOG_DRV("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); - for (int i = 0; i < XMIT_NTB_N; ++i) { - if (ncm_interface.xmit_ready_ntb[i] == NULL) { - ncm_interface.xmit_ready_ntb[i] = ready_ntb; - return; - } + for (int i = 0; i < XMIT_NTB_N; ++i) { + if (ncm_interface.xmit_ready_ntb[i] == NULL) { + ncm_interface.xmit_ready_ntb[i] = ready_ntb; + return; } - TU_LOG1("(EE) xmit_put_ntb_into_ready_list: ready list full\n"); // this should not happen -} // xmit_put_ntb_into_ready_list + } + TU_LOG_DRV("(EE) xmit_put_ntb_into_ready_list: ready list full\n");// this should not happen +} // xmit_put_ntb_into_ready_list - - -static xmit_ntb_t *xmit_get_next_ready_ntb(void) /** * Get the next NTB from the ready list (and remove it from the list). * If the ready list is empty, return NULL. */ -{ - xmit_ntb_t *r = NULL; - - r = ncm_interface.xmit_ready_ntb[0]; - memmove(ncm_interface.xmit_ready_ntb + 0, ncm_interface.xmit_ready_ntb + 1, sizeof(ncm_interface.xmit_ready_ntb) - sizeof(ncm_interface.xmit_ready_ntb[0])); - ncm_interface.xmit_ready_ntb[XMIT_NTB_N - 1] = NULL; +static xmit_ntb_t *xmit_get_next_ready_ntb(void) { + xmit_ntb_t *r = NULL; - TU_LOG3("recv_get_next_ready_ntb: %p\n", r); - return r; -} // xmit_get_next_ready_ntb + r = ncm_interface.xmit_ready_ntb[0]; + memmove(ncm_interface.xmit_ready_ntb + 0, ncm_interface.xmit_ready_ntb + 1, sizeof(ncm_interface.xmit_ready_ntb) - sizeof(ncm_interface.xmit_ready_ntb[0])); + ncm_interface.xmit_ready_ntb[XMIT_NTB_N - 1] = NULL; + TU_LOG_DRV("recv_get_next_ready_ntb: %p\n", r); + return r; +} // xmit_get_next_ready_ntb - -static bool xmit_insert_required_zlp(uint8_t rhport, uint32_t xferred_bytes) /** * Transmit a ZLP if required * @@ -302,252 +284,221 @@ static bool xmit_insert_required_zlp(uint8_t rhport, uint32_t xferred_bytes) * \pre * This must be called from netd_xfer_cb() so that ep_in is ready */ -{ - TU_LOG3("xmit_insert_required_zlp(%d,%d)\n", rhport, xferred_bytes); - - if (xferred_bytes == 0 || xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE != 0) { - return false; - } +static bool xmit_insert_required_zlp(uint8_t rhport, uint32_t xferred_bytes) { + TU_LOG_DRV("xmit_insert_required_zlp(%d,%d)\n", rhport, xferred_bytes); - TU_ASSERT(ncm_interface.itf_data_alt == 1, false); - TU_ASSERT( !usbd_edpt_busy(rhport, ncm_interface.ep_in), false); - - TU_LOG2("xmit_insert_required_zlp! (%u)\n", (unsigned)xferred_bytes); + if (xferred_bytes == 0 || xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE != 0) { + return false; + } - // start transmission of the ZLP - usbd_edpt_xfer(rhport, ncm_interface.ep_in, NULL, 0); + TU_ASSERT(ncm_interface.itf_data_alt == 1, false); + TU_ASSERT(!usbd_edpt_busy(rhport, ncm_interface.ep_in), false); - return true; -} // xmit_insert_required_zlp + TU_LOG_DRV("xmit_insert_required_zlp! (%u)\n", (unsigned) xferred_bytes); + // start transmission of the ZLP + usbd_edpt_xfer(rhport, ncm_interface.ep_in, NULL, 0); + return true; +} // xmit_insert_required_zlp -static void xmit_start_if_possible(uint8_t rhport) /** * Start transmission if it there is a waiting packet and if can be done from interface side. */ -{ - TU_LOG3("xmit_start_if_possible()\n"); - - if (ncm_interface.xmit_tinyusb_ntb != NULL) { - TU_LOG3(" !xmit_start_if_possible 1\n"); - return; - } - if (ncm_interface.itf_data_alt != 1) { - TU_LOG1("(EE) !xmit_start_if_possible 2\n"); - return; - } - if (usbd_edpt_busy(rhport, ncm_interface.ep_in)) { - TU_LOG2(" !xmit_start_if_possible 3\n"); - return; - } +static void xmit_start_if_possible(uint8_t rhport) { + TU_LOG_DRV("xmit_start_if_possible()\n"); + + if (ncm_interface.xmit_tinyusb_ntb != NULL) { + TU_LOG_DRV(" !xmit_start_if_possible 1\n"); + return; + } + if (ncm_interface.itf_data_alt != 1) { + TU_LOG_DRV("(EE) !xmit_start_if_possible 2\n"); + return; + } + if (usbd_edpt_busy(rhport, ncm_interface.ep_in)) { + TU_LOG_DRV(" !xmit_start_if_possible 3\n"); + return; + } + + ncm_interface.xmit_tinyusb_ntb = xmit_get_next_ready_ntb(); + if (ncm_interface.xmit_tinyusb_ntb == NULL) { + if (ncm_interface.xmit_glue_ntb == NULL || ncm_interface.xmit_glue_ntb_datagram_ndx == 0) { + // -> really nothing is waiting + return; + } + ncm_interface.xmit_tinyusb_ntb = ncm_interface.xmit_glue_ntb; + ncm_interface.xmit_glue_ntb = NULL; + } + + #if CFG_TUD_NCM_LOG_LEVEL >= 3 + { + uint16_t len = ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength; + TU_LOG_BUF(3, ncm_interface.xmit_tinyusb_ntb->data[i], len); + } + #endif + + if (ncm_interface.xmit_glue_ntb_datagram_ndx != 1) { + TU_LOG_DRV(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength, ncm_interface.xmit_glue_ntb_datagram_ndx); + } + + // Kick off an endpoint transfer + usbd_edpt_xfer(0, ncm_interface.ep_in, ncm_interface.xmit_tinyusb_ntb->data, ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength); +} // xmit_start_if_possible - ncm_interface.xmit_tinyusb_ntb = xmit_get_next_ready_ntb(); - if (ncm_interface.xmit_tinyusb_ntb == NULL) { - if (ncm_interface.xmit_glue_ntb == NULL || ncm_interface.xmit_glue_ntb_datagram_ndx == 0) { - // -> really nothing is waiting - return; - } - ncm_interface.xmit_tinyusb_ntb = ncm_interface.xmit_glue_ntb; - ncm_interface.xmit_glue_ntb = NULL; - } - -#if CFG_TUSB_DEBUG >= 3 - { - uint16_t len = ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength; - TU_LOG3(" %d\n", len); - for (int i = 0; i < len; ++i) { - TU_LOG3(" %02x", ncm_interface.xmit_tinyusb_ntb->data[i]); - } - TU_LOG3("\n"); - } -#endif - - if (ncm_interface.xmit_glue_ntb_datagram_ndx != 1) { - TU_LOG3(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength, ncm_interface.xmit_glue_ntb_datagram_ndx); - } - - // Kick off an endpoint transfer - usbd_edpt_xfer(0, ncm_interface.ep_in, ncm_interface.xmit_tinyusb_ntb->data, ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength); -} // xmit_start_if_possible - - - -static bool xmit_requested_datagram_fits_into_current_ntb(uint16_t datagram_size) /** * check if a new datagram fits into the current NTB */ -{ - TU_LOG3("xmit_requested_datagram_fits_into_current_ntb(%d) - %p %p\n", datagram_size, ncm_interface.xmit_tinyusb_ntb, ncm_interface.xmit_glue_ntb); - - if (ncm_interface.xmit_glue_ntb == NULL) { - return false; - } - if (ncm_interface.xmit_glue_ntb_datagram_ndx >= CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB) { - return false; - } - if (ncm_interface.xmit_glue_ntb->nth.wBlockLength + datagram_size + XMIT_ALIGN_OFFSET(datagram_size) > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - return false; - } - return true; -} // xmit_requested_datagram_fits_into_current_ntb - +static bool xmit_requested_datagram_fits_into_current_ntb(uint16_t datagram_size) { + TU_LOG_DRV("xmit_requested_datagram_fits_into_current_ntb(%d) - %p %p\n", datagram_size, ncm_interface.xmit_tinyusb_ntb, ncm_interface.xmit_glue_ntb); + if (ncm_interface.xmit_glue_ntb == NULL) { + return false; + } + if (ncm_interface.xmit_glue_ntb_datagram_ndx >= CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB) { + return false; + } + if (ncm_interface.xmit_glue_ntb->nth.wBlockLength + datagram_size + XMIT_ALIGN_OFFSET(datagram_size) > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + return false; + } + return true; +} // xmit_requested_datagram_fits_into_current_ntb -static bool xmit_setup_next_glue_ntb(void) /** * Setup an NTB for the glue logic */ -{ - TU_LOG3("xmit_setup_next_glue_ntb - %p\n", ncm_interface.xmit_glue_ntb); +static bool xmit_setup_next_glue_ntb(void) { + TU_LOG_DRV("xmit_setup_next_glue_ntb - %p\n", ncm_interface.xmit_glue_ntb); - if (ncm_interface.xmit_glue_ntb != NULL) { - // put NTB into waiting list (the new datagram did not fit in) - xmit_put_ntb_into_ready_list(ncm_interface.xmit_glue_ntb); - } + if (ncm_interface.xmit_glue_ntb != NULL) { + // put NTB into waiting list (the new datagram did not fit in) + xmit_put_ntb_into_ready_list(ncm_interface.xmit_glue_ntb); + } - ncm_interface.xmit_glue_ntb = xmit_get_free_ntb(); // get next buffer (if any) - if (ncm_interface.xmit_glue_ntb == NULL) { - TU_LOG3(" xmit_setup_next_glue_ntb - nothing free\n"); // should happen rarely - return false; - } - - ncm_interface.xmit_glue_ntb_datagram_ndx = 0; + ncm_interface.xmit_glue_ntb = xmit_get_free_ntb();// get next buffer (if any) + if (ncm_interface.xmit_glue_ntb == NULL) { + TU_LOG_DRV(" xmit_setup_next_glue_ntb - nothing free\n");// should happen rarely + return false; + } - xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; + ncm_interface.xmit_glue_ntb_datagram_ndx = 0; - // Fill in NTB header - ntb->nth.dwSignature = NTH16_SIGNATURE; - ntb->nth.wHeaderLength = sizeof(ntb->nth); - ntb->nth.wSequence = ncm_interface.xmit_sequence++; - ntb->nth.wBlockLength = sizeof(ntb->nth) + sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); - ntb->nth.wNdpIndex = sizeof(ntb->nth); + xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; - // Fill in NDP16 header and terminator - ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; - ntb->ndp.wLength = sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); - ntb->ndp.wNextNdpIndex = 0; + // Fill in NTB header + ntb->nth.dwSignature = NTH16_SIGNATURE; + ntb->nth.wHeaderLength = sizeof(ntb->nth); + ntb->nth.wSequence = ncm_interface.xmit_sequence++; + ntb->nth.wBlockLength = sizeof(ntb->nth) + sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); + ntb->nth.wNdpIndex = sizeof(ntb->nth); - memset(ntb->ndp_datagram, 0, sizeof(ntb->ndp_datagram)); - return true; -} // xmit_setup_next_glue_ntb + // Fill in NDP16 header and terminator + ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; + ntb->ndp.wLength = sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); + ntb->ndp.wNextNdpIndex = 0; + memset(ntb->ndp_datagram, 0, sizeof(ntb->ndp_datagram)); + return true; +} // xmit_setup_next_glue_ntb //----------------------------------------------------------------------------- // // all the recv_*() stuff (TinyUSB -> driver -> glue logic) // - -static recv_ntb_t *recv_get_free_ntb(void) /** * Return pointer to an available receive buffer or NULL. * Returned buffer (if any) has the size \a CFG_TUD_NCM_OUT_NTB_MAX_SIZE. */ -{ - TU_LOG3("recv_get_free_ntb()\n"); - - for (int i = 0; i < RECV_NTB_N; ++i) { - if (ncm_interface.recv_free_ntb[i] != NULL) { - recv_ntb_t *free = ncm_interface.recv_free_ntb[i]; - ncm_interface.recv_free_ntb[i] = NULL; - return free; - } - } - return NULL; -} // recv_get_free_ntb - +static recv_ntb_t *recv_get_free_ntb(void) { + TU_LOG_DRV("recv_get_free_ntb()\n"); + for (int i = 0; i < RECV_NTB_N; ++i) { + if (ncm_interface.recv_free_ntb[i] != NULL) { + recv_ntb_t *free = ncm_interface.recv_free_ntb[i]; + ncm_interface.recv_free_ntb[i] = NULL; + return free; + } + } + return NULL; +} // recv_get_free_ntb -static recv_ntb_t *recv_get_next_ready_ntb(void) /** * Get the next NTB from the ready list (and remove it from the list). * If the ready list is empty, return NULL. */ -{ - recv_ntb_t *r = NULL; +static recv_ntb_t *recv_get_next_ready_ntb(void) { + recv_ntb_t *r = NULL; - r = ncm_interface.recv_ready_ntb[0]; - memmove(ncm_interface.recv_ready_ntb + 0, ncm_interface.recv_ready_ntb + 1, sizeof(ncm_interface.recv_ready_ntb) - sizeof(ncm_interface.recv_ready_ntb[0])); - ncm_interface.recv_ready_ntb[RECV_NTB_N - 1] = NULL; + r = ncm_interface.recv_ready_ntb[0]; + memmove(ncm_interface.recv_ready_ntb + 0, ncm_interface.recv_ready_ntb + 1, sizeof(ncm_interface.recv_ready_ntb) - sizeof(ncm_interface.recv_ready_ntb[0])); + ncm_interface.recv_ready_ntb[RECV_NTB_N - 1] = NULL; - TU_LOG3("recv_get_next_ready_ntb: %p\n", r); - return r; -} // recv_get_next_ready_ntb + TU_LOG_DRV("recv_get_next_ready_ntb: %p\n", r); + return r; +} // recv_get_next_ready_ntb - - -static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) /** * Put NTB into the receiver free list. */ -{ - TU_LOG3("recv_put_ntb_into_free_list(%p)\n", free_ntb); +static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) { + TU_LOG_DRV("recv_put_ntb_into_free_list(%p)\n", free_ntb); - for (int i = 0; i < RECV_NTB_N; ++i) { - if (ncm_interface.recv_free_ntb[i] == NULL) { - ncm_interface.recv_free_ntb[i] = free_ntb; - return; - } + for (int i = 0; i < RECV_NTB_N; ++i) { + if (ncm_interface.recv_free_ntb[i] == NULL) { + ncm_interface.recv_free_ntb[i] = free_ntb; + return; } - TU_LOG1("(EE) recv_put_ntb_into_free_list - no entry in free list\n"); // this should not happen -} // recv_put_ntb_into_free_list + } + TU_LOG_DRV("(EE) recv_put_ntb_into_free_list - no entry in free list\n");// this should not happen +} // recv_put_ntb_into_free_list - - -static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) /** * \a ready_ntb holds a validated NTB, * put this buffer into the waiting list. */ -{ - TU_LOG3("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); +static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) { + TU_LOG_DRV("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); - for (int i = 0; i < RECV_NTB_N; ++i) { - if (ncm_interface.recv_ready_ntb[i] == NULL) { - ncm_interface.recv_ready_ntb[i] = ready_ntb; - return; - } + for (int i = 0; i < RECV_NTB_N; ++i) { + if (ncm_interface.recv_ready_ntb[i] == NULL) { + ncm_interface.recv_ready_ntb[i] = ready_ntb; + return; } - TU_LOG1("(EE) recv_put_ntb_into_ready_list: ready list full\n"); // this should not happen -} // recv_put_ntb_into_ready_list - - + } + TU_LOG_DRV("(EE) recv_put_ntb_into_ready_list: ready list full\n");// this should not happen +} // recv_put_ntb_into_ready_list -static void recv_try_to_start_new_reception(uint8_t rhport) /** * If possible, start a new reception TinyUSB -> driver. */ -{ - TU_LOG3("recv_try_to_start_new_reception(%d)\n", rhport); - - if (ncm_interface.itf_data_alt != 1) { - return; - } - if (ncm_interface.recv_tinyusb_ntb != NULL) { - return; - } - if (usbd_edpt_busy(rhport, ncm_interface.ep_out)) { - return; - } - - ncm_interface.recv_tinyusb_ntb = recv_get_free_ntb(); - if (ncm_interface.recv_tinyusb_ntb == NULL) { - return; - } - - // initiate transfer - TU_LOG3(" start reception\n"); - bool r = usbd_edpt_xfer(rhport, ncm_interface.ep_out, ncm_interface.recv_tinyusb_ntb->data, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); - if ( !r) { - recv_put_ntb_into_free_list(ncm_interface.recv_tinyusb_ntb); - ncm_interface.recv_tinyusb_ntb = NULL; - } -} // recv_try_to_start_new_reception - - +static void recv_try_to_start_new_reception(uint8_t rhport) { + TU_LOG_DRV("recv_try_to_start_new_reception(%d)\n", rhport); + + if (ncm_interface.itf_data_alt != 1) { + return; + } + if (ncm_interface.recv_tinyusb_ntb != NULL) { + return; + } + if (usbd_edpt_busy(rhport, ncm_interface.ep_out)) { + return; + } + + ncm_interface.recv_tinyusb_ntb = recv_get_free_ntb(); + if (ncm_interface.recv_tinyusb_ntb == NULL) { + return; + } + + // initiate transfer + TU_LOG_DRV(" start reception\n"); + bool r = usbd_edpt_xfer(rhport, ncm_interface.ep_out, ncm_interface.recv_tinyusb_ntb->data, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + if (!r) { + recv_put_ntb_into_free_list(ncm_interface.recv_tinyusb_ntb); + ncm_interface.recv_tinyusb_ntb = NULL; + } +} // recv_try_to_start_new_reception -static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) /** * Validate incoming datagram. * \return true if valid @@ -555,287 +506,243 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) * \note * \a ndp16->wNextNdpIndex != 0 is not supported */ -{ - const nth16_t *nth16 = &(ntb->nth); - - TU_LOG3("recv_validate_datagram(%p, %d)\n", ntb, (int)len); - - // - // check header - // - if (nth16->wHeaderLength != sizeof(nth16_t)) - { - TU_LOG1("(EE) ill nth16 length: %d\n", nth16->wHeaderLength); - return false; - } - if (nth16->dwSignature != NTH16_SIGNATURE) { - TU_LOG1("(EE) ill signature: 0x%08x\n", (unsigned)nth16->dwSignature); - return false; - } - if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - TU_LOG1("(EE) ill min len: %d\n", len); - return false; - } - if (nth16->wBlockLength > len) { - TU_LOG1("(EE) ill block length: %d > %d\n", nth16->wBlockLength, len); - return false; - } - if (nth16->wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - TU_LOG1("(EE) ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); - return false; - } - if (nth16->wNdpIndex < sizeof(nth16) || nth16->wNdpIndex > len - (sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t))) { - TU_LOG1("(EE) ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); - return false; - } +static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) { + const nth16_t *nth16 = &(ntb->nth); - // - // check (first) NDP(16) - // - const ndp16_t *ndp16 = (const ndp16_t *)(ntb->data + nth16->wNdpIndex); + TU_LOG_DRV("recv_validate_datagram(%p, %d)\n", ntb, (int) len); - if (ndp16->wLength < sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)) { - TU_LOG1("(EE) ill ndp16 length: %d\n", ndp16->wLength); - return false; - } - if (ndp16->dwSignature != NDP16_SIGNATURE_NCM0 && ndp16->dwSignature != NDP16_SIGNATURE_NCM1) { - TU_LOG1("(EE) ill signature: 0x%08x\n", (unsigned)ndp16->dwSignature); - return false; - } - if (ndp16->wNextNdpIndex != 0) { - TU_LOG1("(EE) cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); - return false; - } + // check header + if (nth16->wHeaderLength != sizeof(nth16_t)) { + TU_LOG_DRV("(EE) ill nth16 length: %d\n", nth16->wHeaderLength); + return false; + } + if (nth16->dwSignature != NTH16_SIGNATURE) { + TU_LOG_DRV("(EE) ill signature: 0x%08x\n", (unsigned) nth16->dwSignature); + return false; + } + if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t)) { + TU_LOG_DRV("(EE) ill min len: %d\n", len); + return false; + } + if (nth16->wBlockLength > len) { + TU_LOG_DRV("(EE) ill block length: %d > %d\n", nth16->wBlockLength, len); + return false; + } + if (nth16->wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + TU_LOG_DRV("(EE) ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + return false; + } + if (nth16->wNdpIndex < sizeof(nth16) || nth16->wNdpIndex > len - (sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t))) { + TU_LOG_DRV("(EE) ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); + return false; + } - const ndp16_datagram_t *ndp16_datagram = (const ndp16_datagram_t *)(ntb->data + nth16->wNdpIndex + sizeof(ndp16_t)); - int ndx = 0; - uint16_t max_ndx = (uint16_t)((ndp16->wLength - sizeof(ndp16_t)) / sizeof(ndp16_datagram_t)); + // check (first) NDP(16) + const ndp16_t *ndp16 = (const ndp16_t *) (ntb->data + nth16->wNdpIndex); - if (max_ndx > 2) { - // number of datagrams in NTB > 1 - TU_LOG2("<< %d (%d)\n", max_ndx - 1, ntb->nth.wBlockLength); - } - if (ndp16_datagram[max_ndx-1].wDatagramIndex != 0 || ndp16_datagram[max_ndx-1].wDatagramLength != 0) { - TU_LOG2(" max_ndx != 0\n"); - return false; - } - while (ndp16_datagram[ndx].wDatagramIndex != 0 && ndp16_datagram[ndx].wDatagramLength != 0) { - TU_LOG3(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); - if (ndp16_datagram[ndx].wDatagramIndex > len) { - TU_LOG1("(EE) ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); - return false; - } - if (ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength > len) { - TU_LOG1("(EE) ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); - return false; - } - ++ndx; - } + if (ndp16->wLength < sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t)) { + TU_LOG_DRV("(EE) ill ndp16 length: %d\n", ndp16->wLength); + return false; + } + if (ndp16->dwSignature != NDP16_SIGNATURE_NCM0 && ndp16->dwSignature != NDP16_SIGNATURE_NCM1) { + TU_LOG_DRV("(EE) ill signature: 0x%08x\n", (unsigned) ndp16->dwSignature); + return false; + } + if (ndp16->wNextNdpIndex != 0) { + TU_LOG_DRV("(EE) cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); + return false; + } -#if CFG_TUSB_DEBUG >= 3 - for (uint32_t i = 0; i < len; ++i) { - TU_LOG3(" %02x", ntb->data[i]); - } - TU_LOG3("\n"); -#endif + const ndp16_datagram_t *ndp16_datagram = (const ndp16_datagram_t *) (ntb->data + nth16->wNdpIndex + sizeof(ndp16_t)); + int ndx = 0; + uint16_t max_ndx = (uint16_t) ((ndp16->wLength - sizeof(ndp16_t)) / sizeof(ndp16_datagram_t)); - // -> ntb contains a valid packet structure - // ok... I did not check for garbage within the datagram indices... - return true; -} // recv_validate_datagram + if (max_ndx > 2) { // number of datagrams in NTB > 1 + TU_LOG_DRV("<< %d (%d)\n", max_ndx - 1, ntb->nth.wBlockLength); + } + if (ndp16_datagram[max_ndx - 1].wDatagramIndex != 0 || ndp16_datagram[max_ndx - 1].wDatagramLength != 0) { + TU_LOG_DRV(" max_ndx != 0\n"); + return false; + } + while (ndp16_datagram[ndx].wDatagramIndex != 0 && ndp16_datagram[ndx].wDatagramLength != 0) { + TU_LOG_DRV(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); + if (ndp16_datagram[ndx].wDatagramIndex > len) { + TU_LOG_DRV("(EE) ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); + return false; + } + if (ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength > len) { + TU_LOG_DRV("(EE) ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); + return false; + } + ++ndx; + } + #if CFG_TUD_NCM_LOG_LEVEL >= 3 + TU_LOG_BUF(3, ntb->data[i], len); + #endif + // -> ntb contains a valid packet structure + // ok... I did not check for garbage within the datagram indices... + return true; +} // recv_validate_datagram -static void recv_transfer_datagram_to_glue_logic(void) /** * Transfer the next (pending) datagram to the glue logic and return receive buffer if empty. */ -{ - TU_LOG3("recv_transfer_datagram_to_glue_logic()\n"); - - if (ncm_interface.recv_glue_ntb == NULL) { - ncm_interface.recv_glue_ntb = recv_get_next_ready_ntb(); - TU_LOG3(" new buffer for glue logic: %p\n", ncm_interface.recv_glue_ntb); - ncm_interface.recv_glue_ntb_datagram_ndx = 0; - } - - if (ncm_interface.recv_glue_ntb != NULL) { - const ndp16_datagram_t *ndp16_datagram = (ndp16_datagram_t *)(ncm_interface.recv_glue_ntb->data - + ncm_interface.recv_glue_ntb->nth.wNdpIndex - + sizeof(ndp16_t)); - - if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex == 0) { - TU_LOG1("(EE) SOMETHING WENT WRONG 1\n"); - } - else if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength == 0) { - TU_LOG1("(EE) SOMETHING WENT WRONG 2\n"); - } - else { - uint16_t datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex; - uint16_t datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength; - - TU_LOG3(" recv[%d] - %d %d\n", ncm_interface.recv_glue_ntb_datagram_ndx, datagramIndex, datagramLength); - if (tud_network_recv_cb(ncm_interface.recv_glue_ntb->data + datagramIndex, datagramLength)) { - // - // send datagram successfully to glue logic - // - TU_LOG3(" OK\n"); - datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramIndex; - datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramLength; - - if (datagramIndex != 0 && datagramLength != 0) { - // -> next datagram - ++ncm_interface.recv_glue_ntb_datagram_ndx; - } - else { - // end of datagrams reached - recv_put_ntb_into_free_list(ncm_interface.recv_glue_ntb); - ncm_interface.recv_glue_ntb = NULL; - } - } +static void recv_transfer_datagram_to_glue_logic(void) { + TU_LOG_DRV("recv_transfer_datagram_to_glue_logic()\n"); + + if (ncm_interface.recv_glue_ntb == NULL) { + ncm_interface.recv_glue_ntb = recv_get_next_ready_ntb(); + TU_LOG_DRV(" new buffer for glue logic: %p\n", ncm_interface.recv_glue_ntb); + ncm_interface.recv_glue_ntb_datagram_ndx = 0; + } + + if (ncm_interface.recv_glue_ntb != NULL) { + const ndp16_datagram_t *ndp16_datagram = (ndp16_datagram_t *) (ncm_interface.recv_glue_ntb->data + ncm_interface.recv_glue_ntb->nth.wNdpIndex + sizeof(ndp16_t)); + + if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex == 0) { + TU_LOG_DRV("(EE) SOMETHING WENT WRONG 1\n"); + } else if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength == 0) { + TU_LOG_DRV("(EE) SOMETHING WENT WRONG 2\n"); + } else { + uint16_t datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex; + uint16_t datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength; + + TU_LOG_DRV(" recv[%d] - %d %d\n", ncm_interface.recv_glue_ntb_datagram_ndx, datagramIndex, datagramLength); + if (tud_network_recv_cb(ncm_interface.recv_glue_ntb->data + datagramIndex, datagramLength)) { + // send datagram successfully to glue logic + TU_LOG_DRV(" OK\n"); + datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramIndex; + datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramLength; + + if (datagramIndex != 0 && datagramLength != 0) { + // -> next datagram + ++ncm_interface.recv_glue_ntb_datagram_ndx; + } else { + // end of datagrams reached + recv_put_ntb_into_free_list(ncm_interface.recv_glue_ntb); + ncm_interface.recv_glue_ntb = NULL; } + } } -} // recv_transfer_datagram_to_glue_logic - + } +} // recv_transfer_datagram_to_glue_logic //----------------------------------------------------------------------------- // // all the tud_network_*() stuff (glue logic -> driver) // - -bool tud_network_can_xmit(uint16_t size) /** * Check if the glue logic is allowed to call tud_network_xmit(). * This function also fetches a next buffer if required, so that tud_network_xmit() is ready for copy * and transmission operation. */ -{ - TU_LOG3("tud_network_can_xmit(%d)\n", size); - - TU_ASSERT(size <= CFG_TUD_NCM_OUT_NTB_MAX_SIZE - (sizeof(nth16_t) + sizeof(ndp16_t) + 2*sizeof(ndp16_datagram_t)), false); - - if (xmit_requested_datagram_fits_into_current_ntb(size) || xmit_setup_next_glue_ntb()) { - // -> everything is fine - return true; - } - xmit_start_if_possible(ncm_interface.rhport); - TU_LOG2("(II) tud_network_can_xmit: request blocked\n"); // could happen if all xmit buffers are full (but should happen rarely) - return false; -} // tud_network_can_xmit +bool tud_network_can_xmit(uint16_t size) { + TU_LOG_DRV("tud_network_can_xmit(%d)\n", size); + TU_ASSERT(size <= CFG_TUD_NCM_OUT_NTB_MAX_SIZE - (sizeof(nth16_t) + sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t)), false); + if (xmit_requested_datagram_fits_into_current_ntb(size) || xmit_setup_next_glue_ntb()) { + // -> everything is fine + return true; + } + xmit_start_if_possible(ncm_interface.rhport); + TU_LOG_DRV("(II) tud_network_can_xmit: request blocked\n");// could happen if all xmit buffers are full (but should happen rarely) + return false; +} // tud_network_can_xmit -void tud_network_xmit(void *ref, uint16_t arg) /** * Put a datagram into a waiting NTB. * If currently no transmission is started, then initiate transmission. */ -{ - TU_LOG3("tud_network_xmit(%p, %d)\n", ref, arg); - - if (ncm_interface.xmit_glue_ntb == NULL) { - TU_LOG1("(EE) tud_network_xmit: no buffer\n"); // must not happen (really) - return; - } - - xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; +void tud_network_xmit(void *ref, uint16_t arg) { + TU_LOG_DRV("tud_network_xmit(%p, %d)\n", ref, arg); - // copy new datagram to the end of the current NTB - uint16_t size = tud_network_xmit_cb(ntb->data + ntb->nth.wBlockLength, ref, arg); + if (ncm_interface.xmit_glue_ntb == NULL) { + TU_LOG_DRV("(EE) tud_network_xmit: no buffer\n");// must not happen (really) + return; + } - // correct NTB internals - ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramIndex = ntb->nth.wBlockLength; - ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramLength = size; - ncm_interface.xmit_glue_ntb_datagram_ndx += 1; + xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; - ntb->nth.wBlockLength += (uint16_t)(size + XMIT_ALIGN_OFFSET(size)); + // copy new datagram to the end of the current NTB + uint16_t size = tud_network_xmit_cb(ntb->data + ntb->nth.wBlockLength, ref, arg); - if (ntb->nth.wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { - TU_LOG1("(EE) tud_network_xmit: buffer overflow\n"); // must not happen (really) - return; - } + // correct NTB internals + ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramIndex = ntb->nth.wBlockLength; + ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramLength = size; + ncm_interface.xmit_glue_ntb_datagram_ndx += 1; - xmit_start_if_possible(ncm_interface.rhport); -} // tud_network_xmit + ntb->nth.wBlockLength += (uint16_t) (size + XMIT_ALIGN_OFFSET(size)); + if (ntb->nth.wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + TU_LOG_DRV("(EE) tud_network_xmit: buffer overflow\n"); // must not happen (really) + return; + } + xmit_start_if_possible(ncm_interface.rhport); +} // tud_network_xmit -void tud_network_recv_renew(void) /** * Keep the receive logic busy and transfer pending packets to the glue logic. */ -{ - TU_LOG3("tud_network_recv_renew()\n"); +void tud_network_recv_renew(void) { + TU_LOG_DRV("tud_network_recv_renew()\n"); - recv_transfer_datagram_to_glue_logic(); - recv_try_to_start_new_reception(ncm_interface.rhport); -} // tud_network_recv_renew + recv_transfer_datagram_to_glue_logic(); + recv_try_to_start_new_reception(ncm_interface.rhport); +} // tud_network_recv_renew - - -void tud_network_recv_renew_r(uint8_t rhport) /** * Same as tud_network_recv_renew() but knows \a rhport */ -{ - TU_LOG3("tud_network_recv_renew_r(%d)\n", rhport); - - ncm_interface.rhport = rhport; - tud_network_recv_renew(); -} // tud_network_recv_renew +void tud_network_recv_renew_r(uint8_t rhport) { + TU_LOG_DRV("tud_network_recv_renew_r(%d)\n", rhport); + ncm_interface.rhport = rhport; + tud_network_recv_renew(); +} // tud_network_recv_renew //----------------------------------------------------------------------------- // // all the netd_*() stuff (interface TinyUSB -> driver) // -void netd_init(void) /** * Initialize the driver data structures. * Might be called several times. */ -{ - TU_LOG3("netd_init()\n"); +void netd_init(void) { + TU_LOG_DRV("netd_init()\n"); - memset( &ncm_interface, 0, sizeof(ncm_interface)); - - for (int i = 0; i < XMIT_NTB_N; ++i) { - ncm_interface.xmit_free_ntb[i] = ncm_interface.xmit_ntb + i; - } - for (int i = 0; i < RECV_NTB_N; ++i) { - ncm_interface.recv_free_ntb[i] = ncm_interface.recv_ntb + i; - } -} // netd_init + memset(&ncm_interface, 0, sizeof(ncm_interface)); + for (int i = 0; i < XMIT_NTB_N; ++i) { + ncm_interface.xmit_free_ntb[i] = ncm_interface.xmit_ntb + i; + } + for (int i = 0; i < RECV_NTB_N; ++i) { + ncm_interface.recv_free_ntb[i] = ncm_interface.recv_ntb + i; + } +} // netd_init - -bool netd_deinit(void) /** * Deinit driver */ -{ - return true; +bool netd_deinit(void) { + return true; } - - -void netd_reset(uint8_t rhport) /** * Resets the port. * In this driver this is the same as netd_init() */ -{ - (void)rhport; - - TU_LOG3("netd_reset(%d)\n", rhport); +void netd_reset(uint8_t rhport) { + (void) rhport; - netd_init(); -} // netd_reset + netd_init(); +} // netd_reset - - -uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) /** * Open the USB interface. * - parse the USB descriptor \a TUD_CDC_NCM_DESCRIPTOR for itfnum and endpoints @@ -850,174 +757,137 @@ uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16 * - \a ep_notif, \a ep_in and \a ep_out are set * - USB interface is open */ -{ - TU_LOG3("netd_open(%d,%p,%d)\n", rhport, itf_desc, max_len); - - TU_ASSERT(ncm_interface.ep_notif == 0, 0); // assure that the interface is only opened once +uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { + TU_ASSERT(ncm_interface.ep_notif == 0, 0);// assure that the interface is only opened once - ncm_interface.itf_num = itf_desc->bInterfaceNumber; // management interface + ncm_interface.itf_num = itf_desc->bInterfaceNumber;// management interface - // - // skip the two first entries and the following TUSB_DESC_CS_INTERFACE entries - // - uint16_t drv_len = sizeof(tusb_desc_interface_t); - uint8_t const *p_desc = tu_desc_next(itf_desc); - while (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && drv_len <= max_len) { - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); - } - - // - // get notification endpoint - // - TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 0); - TU_ASSERT(usbd_edpt_open(rhport, (tusb_desc_endpoint_t const* ) p_desc), 0); - ncm_interface.ep_notif = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress; + // skip the two first entries and the following TUSB_DESC_CS_INTERFACE entries + uint16_t drv_len = sizeof(tusb_desc_interface_t); + uint8_t const *p_desc = tu_desc_next(itf_desc); + while (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && drv_len <= max_len) { drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); + } - // - // skip the following TUSB_DESC_INTERFACE entries (which must be TUSB_CLASS_CDC_DATA) - // - while (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && drv_len <= max_len) { - tusb_desc_interface_t const *data_itf_desc = (tusb_desc_interface_t const*)p_desc; - TU_ASSERT(data_itf_desc->bInterfaceClass == TUSB_CLASS_CDC_DATA, 0); + // get notification endpoint + TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 0); + TU_ASSERT(usbd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), 0); + ncm_interface.ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress; + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); - } + // skip the following TUSB_DESC_INTERFACE entries (which must be TUSB_CLASS_CDC_DATA) + while (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && drv_len <= max_len) { + tusb_desc_interface_t const *data_itf_desc = (tusb_desc_interface_t const *) p_desc; + TU_ASSERT(data_itf_desc->bInterfaceClass == TUSB_CLASS_CDC_DATA, 0); - // - // a TUSB_DESC_ENDPOINT (actually two) must follow, open these endpoints - // - TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 0); - TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in)); - drv_len += 2 * sizeof(tusb_desc_endpoint_t); - - return drv_len; -} // netd_open + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + // a TUSB_DESC_ENDPOINT (actually two) must follow, open these endpoints + TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 0); + TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in)); + drv_len += 2 * sizeof(tusb_desc_endpoint_t); + return drv_len; +} // netd_open -bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) /** * Handle TinyUSB requests to process transfer events. */ -{ - (void)result; - - TU_LOG3("netd_xfer_cb(%d,%d,%d,%u)\n", rhport, ep_addr, result, (unsigned)xferred_bytes); - - if (ep_addr == ncm_interface.ep_out) { - // - // new NTB received - // - make the NTB valid - // - if ready transfer datagrams to the glue logic for further processing - // - if there is a free receive buffer, initiate reception - // - TU_LOG3(" EP_OUT %d %d %d %u\n", rhport, ep_addr, result, (unsigned)xferred_bytes); - if ( !recv_validate_datagram( ncm_interface.recv_tinyusb_ntb, xferred_bytes)) { - // verification failed: ignore NTB and return it to free - TU_LOG1("(EE) VALIDATION FAILED. WHAT CAN WE DO IN THIS CASE?\n"); - } - else { - // packet ok -> put it into ready list - recv_put_ntb_into_ready_list(ncm_interface.recv_tinyusb_ntb); - } - ncm_interface.recv_tinyusb_ntb = NULL; - tud_network_recv_renew_r(rhport); - } - else if (ep_addr == ncm_interface.ep_in) { - // - // transmission of an NTB finished - // - free the transmitted NTB buffer - // - insert ZLPs when necessary - // - if there is another transmit NTB waiting, try to start transmission - // - TU_LOG3(" EP_IN %d %u\n", ncm_interface.itf_data_alt, (unsigned)xferred_bytes); - xmit_put_ntb_into_free_list(ncm_interface.xmit_tinyusb_ntb); - ncm_interface.xmit_tinyusb_ntb = NULL; - if ( !xmit_insert_required_zlp(rhport, xferred_bytes)) { - xmit_start_if_possible(rhport); - } - } - else if (ep_addr == ncm_interface.ep_notif) { - // - // next transfer on notification channel - // - TU_LOG3(" EP_NOTIF\n"); - notification_xmit(rhport, true); - } - - return true; -} // netd_xfer_cb - - +bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + (void) result; + + if (ep_addr == ncm_interface.ep_out) { + // new NTB received + // - make the NTB valid + // - if ready transfer datagrams to the glue logic for further processing + // - if there is a free receive buffer, initiate reception + if (!recv_validate_datagram(ncm_interface.recv_tinyusb_ntb, xferred_bytes)) { + // verification failed: ignore NTB and return it to free + TU_LOG_DRV("(EE) VALIDATION FAILED. WHAT CAN WE DO IN THIS CASE?\n"); + } else { + // packet ok -> put it into ready list + recv_put_ntb_into_ready_list(ncm_interface.recv_tinyusb_ntb); + } + ncm_interface.recv_tinyusb_ntb = NULL; + tud_network_recv_renew_r(rhport); + } else if (ep_addr == ncm_interface.ep_in) { + // transmission of an NTB finished + // - free the transmitted NTB buffer + // - insert ZLPs when necessary + // - if there is another transmit NTB waiting, try to start transmission + xmit_put_ntb_into_free_list(ncm_interface.xmit_tinyusb_ntb); + ncm_interface.xmit_tinyusb_ntb = NULL; + if (!xmit_insert_required_zlp(rhport, xferred_bytes)) { + xmit_start_if_possible(rhport); + } + } else if (ep_addr == ncm_interface.ep_notif) { + // next transfer on notification channel + notification_xmit(rhport, true); + } + + return true; +} // netd_xfer_cb -bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) /** * Respond to TinyUSB control requests. * At startup transmission of notification packets are done here. */ -{ - TU_LOG3("netd_control_xfer_cb(%d, %d, %p)\n", rhport, stage, request); +bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { + if (stage != CONTROL_STAGE_SETUP) { + return true; + } - if (stage != CONTROL_STAGE_SETUP) { - return true; - } + switch (request->bmRequestType_bit.type) { + case TUSB_REQ_TYPE_STANDARD: - switch (request->bmRequestType_bit.type) { - case TUSB_REQ_TYPE_STANDARD: - TU_LOG3(" TUSB_REQ_TYPE_STANDARD: %d\n", request->bRequest); - - switch (request->bRequest) { - case TUSB_REQ_GET_INTERFACE: { - TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex, false); - - TU_LOG3(" TUSB_REQ_GET_INTERFACE - %d\n", ncm_interface.itf_data_alt); - tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); - } - break; - - case TUSB_REQ_SET_INTERFACE: { - TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex && request->wValue < 2, false); - - ncm_interface.itf_data_alt = (uint8_t)request->wValue; - TU_LOG3(" TUSB_REQ_SET_INTERFACE - %d %d %d\n", ncm_interface.itf_data_alt, request->wIndex, ncm_interface.itf_num); - - if (ncm_interface.itf_data_alt == 1) { - tud_network_recv_renew_r(rhport); - notification_xmit(rhport, false); - } - tud_control_status(rhport, request); - } - break; - - // unsupported request - default: - return false; - } - break; - - case TUSB_REQ_TYPE_CLASS: - TU_VERIFY(ncm_interface.itf_num == request->wIndex, false); - - TU_LOG3(" TUSB_REQ_TYPE_CLASS: %d\n", request->bRequest); - - if (request->bRequest == NCM_GET_NTB_PARAMETERS) { - // transfer NTB parameters to host. - // TODO can one assume, that tud_control_xfer() succeeds? - TU_LOG3(" NCM_GET_NTB_PARAMETERS\n"); - tud_control_xfer(rhport, request, (void*) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); - } - break; - - // unsupported request - default: - return false ; - } + switch (request->bRequest) { + case TUSB_REQ_GET_INTERFACE: { + TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex, false); - return true; -} // netd_control_xfer_cb + tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); + } break; -#endif // ECLIPSE_GUI || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) + case TUSB_REQ_SET_INTERFACE: { + TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex && request->wValue < 2, false); + + ncm_interface.itf_data_alt = (uint8_t) request->wValue; + + if (ncm_interface.itf_data_alt == 1) { + tud_network_recv_renew_r(rhport); + notification_xmit(rhport, false); + } + tud_control_status(rhport, request); + } break; + + // unsupported request + default: + return false; + } + break; + + case TUSB_REQ_TYPE_CLASS: + TU_VERIFY(ncm_interface.itf_num == request->wIndex, false); + switch (request->bRequest) { + case NCM_GET_NTB_PARAMETERS: { + // transfer NTB parameters to host. + tud_control_xfer(rhport, request, (void *) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); + } break; + + // unsupported request + default: + return false; + } + break; + // unsupported request + default: + return false; + } + + return true; +} // netd_control_xfer_cb + +#endif // ( CFG_TUD_ENABLED && CFG_TUD_NCM ) -- cgit v1.3.1 From d25ee82d3f689dcf22e44246b61f58756195581d Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 7 May 2024 00:17:09 +0200 Subject: Reformat net_lwip_webserver example. --- examples/device/net_lwip_webserver/src/main.c | 113 +++++++++------------ .../device/net_lwip_webserver/src/tusb_config.h | 50 +++++---- 2 files changed, 78 insertions(+), 85 deletions(-) diff --git a/examples/device/net_lwip_webserver/src/main.c b/examples/device/net_lwip_webserver/src/main.c index 7d98aacbc..e6f5faeb6 100644 --- a/examples/device/net_lwip_webserver/src/main.c +++ b/examples/device/net_lwip_webserver/src/main.c @@ -48,12 +48,13 @@ try changing the first byte of tud_network_mac_address[] below from 0x02 to 0x00 #include "dhserver.h" #include "dnserver.h" +#include "httpd.h" +#include "lwip/ethip6.h" #include "lwip/init.h" #include "lwip/timeouts.h" -#include "lwip/ethip6.h" -#include "httpd.h" -#define INIT_IP4(a,b,c,d) { PP_HTONL(LWIP_MAKEU32(a,b,c,d)) } +#define INIT_IP4(a, b, c, d) \ + { PP_HTONL(LWIP_MAKEU32(a, b, c, d)) } /* lwip context */ static struct netif netif_data; @@ -64,44 +65,40 @@ static struct pbuf *received_frame; /* this is used by this code, ./class/net/net_driver.c, and usb_descriptors.c */ /* ideally speaking, this should be generated from the hardware's unique ID (if available) */ /* it is suggested that the first byte is 0x02 to indicate a link-local address */ -uint8_t tud_network_mac_address[6] = {0x02,0x02,0x84,0x6A,0x96,0x00}; +uint8_t tud_network_mac_address[6] = {0x02, 0x02, 0x84, 0x6A, 0x96, 0x00}; /* network parameters of this MCU */ -static const ip4_addr_t ipaddr = INIT_IP4(192, 168, 7, 1); +static const ip4_addr_t ipaddr = INIT_IP4(192, 168, 7, 1); static const ip4_addr_t netmask = INIT_IP4(255, 255, 255, 0); static const ip4_addr_t gateway = INIT_IP4(0, 0, 0, 0); /* database IP addresses that can be offered to the host; this must be in RAM to store assigned MAC addresses */ -static dhcp_entry_t entries[] = -{ - /* mac ip address lease time */ - { {0}, INIT_IP4(192, 168, 7, 2), 24 * 60 * 60 }, - { {0}, INIT_IP4(192, 168, 7, 3), 24 * 60 * 60 }, - { {0}, INIT_IP4(192, 168, 7, 4), 24 * 60 * 60 }, +static dhcp_entry_t entries[] = { + /* mac ip address lease time */ + {{0}, INIT_IP4(192, 168, 7, 2), 24 * 60 * 60}, + {{0}, INIT_IP4(192, 168, 7, 3), 24 * 60 * 60}, + {{0}, INIT_IP4(192, 168, 7, 4), 24 * 60 * 60}, }; -static const dhcp_config_t dhcp_config = -{ - .router = INIT_IP4(0, 0, 0, 0), /* router address (if any) */ - .port = 67, /* listen port */ - .dns = INIT_IP4(192, 168, 7, 1), /* dns server (if any) */ - "usb", /* dns suffix */ - TU_ARRAY_SIZE(entries), /* num entry */ - entries /* entries */ +static const dhcp_config_t dhcp_config = { + .router = INIT_IP4(0, 0, 0, 0), /* router address (if any) */ + .port = 67, /* listen port */ + .dns = INIT_IP4(192, 168, 7, 1), /* dns server (if any) */ + "usb", /* dns suffix */ + TU_ARRAY_SIZE(entries), /* num entry */ + entries /* entries */ }; -static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) -{ - (void)netif; - for (;;) - { +static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) { + (void) netif; + + for (;;) { /* if TinyUSB isn't ready, we must signal back to lwip that there is nothing we can do */ if (!tud_ready()) return ERR_USE; /* if the network driver can accept another packet, we make it happen */ - if (tud_network_can_xmit(p->tot_len)) - { + if (tud_network_can_xmit(p->tot_len)) { tud_network_xmit(p, 0 /* unused for this example */); return ERR_OK; } @@ -111,20 +108,17 @@ static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) } } -static err_t ip4_output_fn(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr) -{ +static err_t ip4_output_fn(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr) { return etharp_output(netif, p, addr); } #if LWIP_IPV6 -static err_t ip6_output_fn(struct netif *netif, struct pbuf *p, const ip6_addr_t *addr) -{ +static err_t ip6_output_fn(struct netif *netif, struct pbuf *p, const ip6_addr_t *addr) { return ethip6_output(netif, p, addr); } #endif -static err_t netif_init_cb(struct netif *netif) -{ +static err_t netif_init_cb(struct netif *netif) { LWIP_ASSERT("netif != NULL", (netif != NULL)); netif->mtu = CFG_TUD_NET_MTU; netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; @@ -139,8 +133,7 @@ static err_t netif_init_cb(struct netif *netif) return ERR_OK; } -static void init_lwip(void) -{ +static void init_lwip(void) { struct netif *netif = &netif_data; lwip_init(); @@ -158,28 +151,23 @@ static void init_lwip(void) } /* handle any DNS requests from dns-server */ -bool dns_query_proc(const char *name, ip4_addr_t *addr) -{ - if (0 == strcmp(name, "tiny.usb")) - { +bool dns_query_proc(const char *name, ip4_addr_t *addr) { + if (0 == strcmp(name, "tiny.usb")) { *addr = ipaddr; return true; } return false; } -bool tud_network_recv_cb(const uint8_t *src, uint16_t size) -{ +bool tud_network_recv_cb(const uint8_t *src, uint16_t size) { /* this shouldn't happen, but if we get another packet before parsing the previous, we must signal our inability to accept it */ if (received_frame) return false; - if (size) - { + if (size) { struct pbuf *p = pbuf_alloc(PBUF_RAW, size, PBUF_POOL); - if (p) - { + if (p) { /* pbuf_alloc() has already initialized struct; all we need to do is copy the data */ memcpy(p->payload, src, size); @@ -191,20 +179,17 @@ bool tud_network_recv_cb(const uint8_t *src, uint16_t size) return true; } -uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) -{ - struct pbuf *p = (struct pbuf *)ref; +uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) { + struct pbuf *p = (struct pbuf *) ref; - (void)arg; /* unused for this example */ + (void) arg; /* unused for this example */ return pbuf_copy_partial(p, dst, p->tot_len, 0); } -static void service_traffic(void) -{ +static void service_traffic(void) { /* handle any packet received by tud_network_recv_cb() */ - if (received_frame) - { + if (received_frame) { ethernet_input(received_frame, &netif_data); pbuf_free(received_frame); received_frame = NULL; @@ -214,18 +199,15 @@ static void service_traffic(void) sys_check_timeouts(); } -void tud_network_init_cb(void) -{ +void tud_network_init_cb(void) { /* if the network is re-initializing and we have a leftover packet, we must do a cleanup */ - if (received_frame) - { + if (received_frame) { pbuf_free(received_frame); received_frame = NULL; } } -int main(void) -{ +int main(void) { /* initialize TinyUSB */ board_init(); @@ -243,8 +225,8 @@ int main(void) while (dnserv_init(IP_ADDR_ANY, 53, dns_query_proc) != ERR_OK); httpd_init(); - while (1) - { + + while (1) { tud_task(); service_traffic(); } @@ -253,17 +235,14 @@ int main(void) } /* lwip has provision for using a mutex, when applicable */ -sys_prot_t sys_arch_protect(void) -{ +sys_prot_t sys_arch_protect(void) { return 0; } -void sys_arch_unprotect(sys_prot_t pval) -{ - (void)pval; +void sys_arch_unprotect(sys_prot_t pval) { + (void) pval; } /* lwip needs a millisecond time source, and the TinyUSB board support code has one available */ -uint32_t sys_now(void) -{ +uint32_t sys_now(void) { return board_millis(); } diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h index 841525cad..e0db3113c 100644 --- a/examples/device/net_lwip_webserver/src/tusb_config.h +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -27,21 +27,23 @@ #define _TUSB_CONFIG_H_ #ifdef __cplusplus - extern "C" { +extern "C" { #endif +#include "lwipopts.h" + //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT -#define BOARD_TUD_RHPORT 0 + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED -#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- @@ -50,22 +52,22 @@ // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU -#error CFG_TUSB_MCU must be defined + #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE + #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG -#define CFG_TUSB_DEBUG 0 + #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack -#define CFG_TUD_ENABLED 1 +#define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY -#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put @@ -75,21 +77,33 @@ * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION -#define CFG_TUSB_MEM_SECTION + #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) + #define CFG_TUSB_MEM_ALIGN __attribute__((aligned(4))) #endif -// number of NCM transfer blocks for reception side (only valid if NCM is selected below) +//-------------------------------------------------------------------- +// NCM CLASS CONFIGURATION, SEE "ncm.h" FOR PERFORMANCE TUNNING +//-------------------------------------------------------------------- + +// Must be >> MTU +// Can be set to 2048 without impact +#define CFG_TUD_NCM_IN_NTB_MAX_SIZE (2 * TCP_MSS + 100) + +// Must be >> MTU +// Can be set to smaller values if wNtbOutMaxDatagrams==1 +#define CFG_TUD_NCM_OUT_NTB_MAX_SIZE (2 * TCP_MSS + 100) + +// Number of NCM transfer blocks for reception side #ifndef CFG_TUD_NCM_OUT_NTB_N -#define CFG_TUD_NCM_OUT_NTB_N 2 + #define CFG_TUD_NCM_OUT_NTB_N 1 #endif -// number of NCM transfer blocks for transmission side (only valid if NCM is selected below) +// Number of NCM transfer blocks for transmission side #ifndef CFG_TUD_NCM_IN_NTB_N -#define CFG_TUD_NCM_IN_NTB_N 3 + #define CFG_TUD_NCM_IN_NTB_N 1 #endif //-------------------------------------------------------------------- @@ -97,18 +111,18 @@ //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE -#define CFG_TUD_ENDPOINT0_SIZE 64 + #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// // Network class has 2 drivers: ECM/RNDIS and NCM. // Only one of the drivers can be enabled -#define CFG_TUD_ECM_RNDIS 1 -#define CFG_TUD_NCM (1-CFG_TUD_ECM_RNDIS) +#define CFG_TUD_ECM_RNDIS 1 +#define CFG_TUD_NCM (1 - CFG_TUD_ECM_RNDIS) #ifdef __cplusplus - } +} #endif #endif /* _TUSB_CONFIG_H_ */ -- cgit v1.3.1 From 63d5103f42f5da11e08566a107c85b358e3d11aa Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 7 May 2024 00:18:31 +0200 Subject: Increase TCP_WND for better performance. --- examples/device/net_lwip_webserver/src/lwipopts.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/device/net_lwip_webserver/src/lwipopts.h b/examples/device/net_lwip_webserver/src/lwipopts.h index 336c9243d..41e8f0d67 100644 --- a/examples/device/net_lwip_webserver/src/lwipopts.h +++ b/examples/device/net_lwip_webserver/src/lwipopts.h @@ -48,8 +48,8 @@ #define LWIP_IP_ACCEPT_UDP_PORT(p) ((p) == PP_NTOHS(67)) #define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/) -#define TCP_SND_BUF (2 * TCP_MSS) -#define TCP_WND (TCP_MSS) +#define TCP_SND_BUF (4 * TCP_MSS) +#define TCP_WND (4 * TCP_MSS) #define ETHARP_SUPPORT_STATIC_ENTRIES 1 @@ -59,7 +59,7 @@ #define LWIP_SINGLE_NETIF 1 -#define PBUF_POOL_SIZE 2 +#define PBUF_POOL_SIZE 4 #define HTTPD_USE_CUSTOM_FSDATA 0 -- cgit v1.3.1 From 0f4ea8e9182c3f1f526e2ff5447ca31c5c7d8709 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 7 May 2024 00:23:50 +0200 Subject: Enable NCM + iperf for MCU with bigger RAM. --- examples/device/net_lwip_webserver/CMakeLists.txt | 1 + examples/device/net_lwip_webserver/Makefile | 1 + examples/device/net_lwip_webserver/src/main.c | 8 ++++++++ examples/device/net_lwip_webserver/src/tusb_config.h | 14 +++++++++++++- 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/examples/device/net_lwip_webserver/CMakeLists.txt b/examples/device/net_lwip_webserver/CMakeLists.txt index a16b8bd71..c39fd32c5 100644 --- a/examples/device/net_lwip_webserver/CMakeLists.txt +++ b/examples/device/net_lwip_webserver/CMakeLists.txt @@ -74,6 +74,7 @@ target_sources(${PROJECT} PUBLIC ${LWIP}/src/netif/slipif.c ${LWIP}/src/apps/http/httpd.c ${LWIP}/src/apps/http/fs.c + ${LWIP}/src/apps/lwiperf/lwiperf.c ) # due to warnings from other net source, we need to prevent error from some of the warnings options diff --git a/examples/device/net_lwip_webserver/Makefile b/examples/device/net_lwip_webserver/Makefile index 22426ba0d..141532466 100644 --- a/examples/device/net_lwip_webserver/Makefile +++ b/examples/device/net_lwip_webserver/Makefile @@ -63,6 +63,7 @@ SRC_C += \ lib/lwip/src/netif/slipif.c \ lib/lwip/src/apps/http/httpd.c \ lib/lwip/src/apps/http/fs.c \ + lib/lwip/src/apps/lwiperf/lwiperf.c \ lib/networking/dhserver.c \ lib/networking/dnserver.c \ lib/networking/rndis_reports.c diff --git a/examples/device/net_lwip_webserver/src/main.c b/examples/device/net_lwip_webserver/src/main.c index e6f5faeb6..791e09b4f 100644 --- a/examples/device/net_lwip_webserver/src/main.c +++ b/examples/device/net_lwip_webserver/src/main.c @@ -53,6 +53,10 @@ try changing the first byte of tud_network_mac_address[] below from 0x02 to 0x00 #include "lwip/init.h" #include "lwip/timeouts.h" +#ifdef INCLUDE_IPERF + #include "lwip/apps/lwiperf.h" +#endif + #define INIT_IP4(a, b, c, d) \ { PP_HTONL(LWIP_MAKEU32(a, b, c, d)) } @@ -225,6 +229,10 @@ int main(void) { while (dnserv_init(IP_ADDR_ANY, 53, dns_query_proc) != ERR_OK); httpd_init(); +#ifdef INCLUDE_IPERF + // test with: iperf -c 192.168.7.1 -e -i 1 -M 5000 -l 8192 -r + lwiperf_start_tcp_server_default(NULL, NULL); +#endif while (1) { tud_task(); diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h index e0db3113c..ae5e67513 100644 --- a/examples/device/net_lwip_webserver/src/tusb_config.h +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -84,6 +84,18 @@ extern "C" { #define CFG_TUSB_MEM_ALIGN __attribute__((aligned(4))) #endif +// Use different configurations to test all net devices (also due to resource limitations) +#if TU_CHECK_MCU(OPT_MCU_LPC15XX, OPT_MCU_LPC40XX, OPT_MCU_LPC51UXX, OPT_MCU_LPC54) + #define USE_ECM 1 +#elif TU_CHECK_MCU(OPT_MCU_SAMD21, OPT_MCU_SAML21, OPT_MCU_SAML22) + #define USE_ECM 1 +#elif TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F1) + #define USE_ECM 1 +#else + #define USE_ECM 0 + #define INCLUDE_IPERF +#endif + //-------------------------------------------------------------------- // NCM CLASS CONFIGURATION, SEE "ncm.h" FOR PERFORMANCE TUNNING //-------------------------------------------------------------------- @@ -118,7 +130,7 @@ extern "C" { // Network class has 2 drivers: ECM/RNDIS and NCM. // Only one of the drivers can be enabled -#define CFG_TUD_ECM_RNDIS 1 +#define CFG_TUD_ECM_RNDIS USE_ECM #define CFG_TUD_NCM (1 - CFG_TUD_ECM_RNDIS) #ifdef __cplusplus -- cgit v1.3.1 From e5d92c4ea736669445d728d6374f0e1b00c9eb15 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 7 May 2024 00:37:57 +0200 Subject: Fix CI. --- examples/device/net_lwip_webserver/skip.txt | 2 ++ examples/device/net_lwip_webserver/src/tusb_config.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/device/net_lwip_webserver/skip.txt b/examples/device/net_lwip_webserver/skip.txt index 75aa2ef14..bb3ff7885 100644 --- a/examples/device/net_lwip_webserver/skip.txt +++ b/examples/device/net_lwip_webserver/skip.txt @@ -1,9 +1,11 @@ mcu:LPC11UXX mcu:LPC13XX +mcu:LPC15XX mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 mcu:STM32L0 +mcu:STM32F0 mcu:KINETIS_KL family:broadcom_64bit family:broadcom_32bit diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h index ae5e67513..d3e094517 100644 --- a/examples/device/net_lwip_webserver/src/tusb_config.h +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -97,7 +97,7 @@ extern "C" { #endif //-------------------------------------------------------------------- -// NCM CLASS CONFIGURATION, SEE "ncm.h" FOR PERFORMANCE TUNNING +// NCM CLASS CONFIGURATION, SEE "ncm.h" FOR PERFORMANCE TUNING //-------------------------------------------------------------------- // Must be >> MTU -- cgit v1.3.1 From d01b2cfc0e25e6d64f8d7a2d764c2620e0d9d71f Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Tue, 7 May 2024 20:17:48 +1000 Subject: Add option to make CDC TX buffer persistent. --- src/class/cdc/cdc_device.c | 2 ++ src/class/cdc/cdc_device.h | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 2e0a0c30d..f36725eba 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -295,7 +295,9 @@ void cdcd_reset(uint8_t rhport) tu_memclr(p_cdc, ITF_MEM_RESET_SIZE); tu_fifo_clear(&p_cdc->rx_ff); + #if !CFG_TUD_CDC_PERSISTENT_TX_BUFF tu_fifo_clear(&p_cdc->tx_ff); + #endif tu_fifo_set_overwritable(&p_cdc->tx_ff, true); } } diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 20e908451..db709b3bc 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -41,6 +41,12 @@ #define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #endif +// By default the TX fifo buffer is cleared on connect / bus reset. +// Enable this to persist any data in the fifo instead. +#ifndef CFG_TUD_CDC_PERSISTENT_TX_BUFF + #define CFG_TUD_CDC_PERSISTENT_TX_BUFF (0) +#endif + #ifdef __cplusplus extern "C" { #endif -- cgit v1.3.1 From 73d61fa2b8af7ce01d1771a315775e01fc9b5825 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 8 May 2024 21:03:49 +0200 Subject: Migrate to weak default implementation. --- src/class/audio/audio_device.c | 252 ++++++++++++++++++++++++++--------------- src/class/audio/audio_device.h | 32 +++--- 2 files changed, 179 insertions(+), 105 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index dd82d54ac..555ecd4ea 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -429,6 +429,138 @@ typedef struct #define ITF_MEM_RESET_SIZE offsetof(audiod_function_t, ctrl_buf) +//--------------------------------------------------------------------+ +// WEAK FUNCTION STUBS +//--------------------------------------------------------------------+ + +#if CFG_TUD_AUDIO_ENABLE_EP_IN +TU_ATTR_WEAK bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t func_id, uint8_t ep_in, uint8_t cur_alt_setting) { + (void) rhport; + (void) func_id; + (void) ep_in; + (void) cur_alt_setting; + return true; +} + +TU_ATTR_WEAK bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t func_id, uint8_t ep_in, uint8_t cur_alt_setting) { + (void) rhport; + (void) n_bytes_copied; + (void) func_id; + (void) ep_in; + (void) cur_alt_setting; + return true; +} +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT +TU_ATTR_WEAK bool tud_audio_rx_done_pre_read_cb(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting) { + (void) rhport; + (void) n_bytes_received; + (void) func_id; + (void) ep_out; + (void) cur_alt_setting; + return true; +} + +TU_ATTR_WEAK bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting) { + (void) rhport; + (void) n_bytes_received; + (void) func_id; + (void) ep_out; + (void) cur_alt_setting; + return true; +} +#endif + +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +TU_ATTR_WEAK void tud_audio_fb_done_cb(uint8_t func_id) { + (void) func_id; +} + +TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param) { + (void) func_id; + (void) alt_itf; + feedback_param->method = AUDIO_FEEDBACK_METHOD_DISABLED; +} +#endif + +TU_ATTR_WEAK TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift) { + (void) func_id; + (void) frame_number; + (void) interval_shift; +} + +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP +TU_ATTR_WEAK void tud_audio_int_done_cb(uint8_t rhport) { + (void) rhport; +} +#endif + +// Invoked when audio set interface request received +TU_ATTR_WEAK bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request) { + (void) rhport; + (void) p_request; + return true; +} + +// Invoked when audio set interface request received which closes an EP +TU_ATTR_WEAK bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request) { + (void) rhport; + (void) p_request; + return true; +} + +// Invoked when audio class specific set request received for an EP +TU_ATTR_WEAK bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) { + (void) rhport; + (void) p_request; + (void) pBuff; + TU_LOG2(" No EP set request callback available!\r\n"); + return false; // In case no callback function is present or request can not be conducted we stall it +} + +// Invoked when audio class specific set request received for an interface +TU_ATTR_WEAK bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) { + (void) rhport; + (void) p_request; + (void) pBuff; + TU_LOG2(" No interface set request callback available!\r\n"); + return false; // In case no callback function is present or request can not be conducted we stall it +} + +// Invoked when audio class specific set request received for an entity +TU_ATTR_WEAK bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) { + (void) rhport; + (void) p_request; + (void) pBuff; + TU_LOG2(" No entity set request callback available!\r\n"); + return false; // In case no callback function is present or request can not be conducted we stall it +} + +// Invoked when audio class specific get request received for an EP +TU_ATTR_WEAK bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request) { + (void) rhport; + (void) p_request; + TU_LOG2(" No EP get request callback available!\r\n"); + return false; // Stall +} + +// Invoked when audio class specific get request received for an interface +TU_ATTR_WEAK bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request) { + (void) rhport; + (void) p_request; + TU_LOG2(" No interface get request callback available!\r\n"); + return false; // Stall +} + +// Invoked when audio class specific get request received for an entity +TU_ATTR_WEAK bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request) { + (void) rhport; + (void) p_request; + TU_LOG2(" No entity get request callback available!\r\n"); + return false; // Stall +} + //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ @@ -557,17 +689,11 @@ static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t uint8_t const *dummy2; uint8_t idx_audio_fct = 0; - if (tud_audio_rx_done_pre_read_cb || tud_audio_rx_done_post_read_cb) - { - idx_audio_fct = audiod_get_audio_fct_idx(audio); - TU_VERIFY(audiod_get_AS_interface_index(audio->ep_out_as_intf_num, audio, &idxItf, &dummy2)); - } + idx_audio_fct = audiod_get_audio_fct_idx(audio); + TU_VERIFY(audiod_get_AS_interface_index(audio->ep_out_as_intf_num, audio, &idxItf, &dummy2)); // Call a weak callback here - a possibility for user to get informed an audio packet was received and data gets now loaded into EP FIFO (or decoded into support RX software FIFO) - if (tud_audio_rx_done_pre_read_cb) - { - TU_VERIFY(tud_audio_rx_done_pre_read_cb(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->alt_setting[idxItf])); - } + TU_VERIFY(tud_audio_rx_done_pre_read_cb(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->alt_setting[idxItf])); #if CFG_TUD_AUDIO_ENABLE_DECODING @@ -628,10 +754,7 @@ static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t #endif // Call a weak callback here - a possibility for user to get informed decoding was completed - if (tud_audio_rx_done_post_read_cb) - { - TU_VERIFY(tud_audio_rx_done_post_read_cb(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->alt_setting[idxItf])); - } + TU_VERIFY(tud_audio_rx_done_post_read_cb(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->alt_setting[idxItf])); return true; } @@ -865,7 +988,7 @@ static bool audiod_tx_done_cb(uint8_t rhport, audiod_function_t * audio) // Call a weak callback here - a possibility for user to get informed former TX was completed and data gets now loaded into EP in buffer (in case FIFOs are used) or // if no FIFOs are used the user may use this call back to load its data into the EP IN buffer by use of tud_audio_n_write_ep_in_buffer(). - if (tud_audio_tx_done_pre_load_cb) TU_VERIFY(tud_audio_tx_done_pre_load_cb(rhport, idx_audio_fct, audio->ep_in, audio->alt_setting[idxItf])); + TU_VERIFY(tud_audio_tx_done_pre_load_cb(rhport, idx_audio_fct, audio->ep_in, audio->alt_setting[idxItf])); // Send everything in ISO EP FIFO uint16_t n_bytes_tx; @@ -928,7 +1051,7 @@ static bool audiod_tx_done_cb(uint8_t rhport, audiod_function_t * audio) #endif // Call a weak callback here - a possibility for user to get informed former TX was completed and how many bytes were loaded for the next frame - if (tud_audio_tx_done_post_load_cb) TU_VERIFY(tud_audio_tx_done_post_load_cb(rhport, n_bytes_tx, idx_audio_fct, audio->ep_in, audio->alt_setting[idxItf])); + TU_VERIFY(tud_audio_tx_done_post_load_cb(rhport, n_bytes_tx, idx_audio_fct, audio->ep_in, audio->alt_setting[idxItf])); return true; } @@ -1723,7 +1846,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #endif // Invoke callback - can be used to stop data sampling - if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request)); + TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request)); audio->ep_in = 0; // Necessary? @@ -1754,7 +1877,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #endif // Invoke callback - can be used to stop data sampling - if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request)); + TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request)); audio->ep_out = 0; // Necessary? @@ -1870,9 +1993,6 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * { audio->ep_fb = ep_addr; audio->feedback.frame_shift = desc_ep->bInterval -1; - - // Enable SOF interrupt if callback is implemented - if (tud_audio_feedback_interval_isr) usbd_sof_enable(rhport, true); } #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -1885,11 +2005,11 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * TU_VERIFY(foundEPs == nEps); // Invoke one callback for a final set interface - if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - // Prepare feedback computation if callback is available - if (tud_audio_feedback_params_cb) + // Prepare feedback computation if endpoint is available + if(audio->ep_fb != 0) { audio_feedback_params_t fb_param; @@ -1907,6 +2027,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT: case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2: audiod_set_fb_params_freq(audio, fb_param.sample_freq, fb_param.frequency.mclk_freq); + // Enable SOF interrupt + usbd_sof_enable(rhport, true); break; case AUDIO_FEEDBACK_METHOD_FIFO_COUNT: @@ -1983,35 +2105,19 @@ static bool audiod_control_complete(uint8_t rhport, tusb_control_request_t const if (entityID != 0) { - if (tud_audio_set_req_entity_cb) - { - // Check if entity is present and get corresponding driver index - TU_VERIFY(audiod_verify_entity_exists(itf, entityID, &func_id)); + // Check if entity is present and get corresponding driver index + TU_VERIFY(audiod_verify_entity_exists(itf, entityID, &func_id)); - // Invoke callback - return tud_audio_set_req_entity_cb(rhport, p_request, _audiod_fct[func_id].ctrl_buf); - } - else - { - TU_LOG2(" No entity set request callback available!\r\n"); - return false; // In case no callback function is present or request can not be conducted we stall it - } + // Invoke callback + return tud_audio_set_req_entity_cb(rhport, p_request, _audiod_fct[func_id].ctrl_buf); } else { - if (tud_audio_set_req_itf_cb) - { - // Find index of audio driver structure and verify interface really exists - TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); + // Find index of audio driver structure and verify interface really exists + TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); - // Invoke callback - return tud_audio_set_req_itf_cb(rhport, p_request, _audiod_fct[func_id].ctrl_buf); - } - else - { - TU_LOG2(" No interface set request callback available!\r\n"); - return false; // In case no callback function is present or request can not be conducted we stall it - } + // Invoke callback + return tud_audio_set_req_itf_cb(rhport, p_request, _audiod_fct[func_id].ctrl_buf); } } break; @@ -2020,19 +2126,11 @@ static bool audiod_control_complete(uint8_t rhport, tusb_control_request_t const { uint8_t ep = TU_U16_LOW(p_request->wIndex); - if (tud_audio_set_req_ep_cb) - { - // Check if entity is present and get corresponding driver index - TU_VERIFY(audiod_verify_ep_exists(ep, &func_id)); + // Check if entity is present and get corresponding driver index + TU_VERIFY(audiod_verify_ep_exists(ep, &func_id)); - // Invoke callback - return tud_audio_set_req_ep_cb(rhport, p_request, _audiod_fct[func_id].ctrl_buf); - } - else - { - TU_LOG2(" No EP set request callback available!\r\n"); - return false; // In case no callback function is present or request can not be conducted we stall it - } + // Invoke callback + return tud_audio_set_req_ep_cb(rhport, p_request, _audiod_fct[func_id].ctrl_buf); } break; // Unknown/Unsupported recipient @@ -2089,15 +2187,7 @@ static bool audiod_control_request(uint8_t rhport, tusb_control_request_t const // In case we got a get request invoke callback - callback needs to answer as defined in UAC2 specification page 89 - 5. Requests if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) { - if (tud_audio_get_req_entity_cb) - { - return tud_audio_get_req_entity_cb(rhport, p_request); - } - else - { - TU_LOG2(" No entity get request callback available!\r\n"); - return false; // Stall - } + return tud_audio_get_req_entity_cb(rhport, p_request); } } else @@ -2108,15 +2198,7 @@ static bool audiod_control_request(uint8_t rhport, tusb_control_request_t const // In case we got a get request invoke callback - callback needs to answer as defined in UAC2 specification page 89 - 5. Requests if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) { - if (tud_audio_get_req_itf_cb) - { - return tud_audio_get_req_itf_cb(rhport, p_request); - } - else - { - TU_LOG2(" No interface get request callback available!\r\n"); - return false; // Stall - } + return tud_audio_get_req_itf_cb(rhport, p_request); } } } @@ -2132,15 +2214,7 @@ static bool audiod_control_request(uint8_t rhport, tusb_control_request_t const // In case we got a get request invoke callback - callback needs to answer as defined in UAC2 specification page 89 - 5. Requests if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) { - if (tud_audio_get_req_ep_cb) - { - return tud_audio_get_req_ep_cb(rhport, p_request); - } - else - { - TU_LOG2(" No EP get request callback available!\r\n"); - return false; // Stall - } + return tud_audio_get_req_ep_cb(rhport, p_request); } } break; @@ -2195,7 +2269,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 // I assume here, that things above are handled by PHY // All transmission is done - what remains to do is to inform job was completed - if (tud_audio_int_done_cb) tud_audio_int_done_cb(rhport); + tud_audio_int_done_cb(rhport); return true; } @@ -2236,7 +2310,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 // Transmission of feedback EP finished if (audio->ep_fb == ep_addr) { - if (tud_audio_fb_done_cb) tud_audio_fb_done_cb(func_id); + tud_audio_fb_done_cb(func_id); // Schedule a transmit with the new value if EP is not busy if (usbd_edpt_claim(rhport, audio->ep_fb)) @@ -2397,7 +2471,7 @@ TU_ATTR_FAST_FUNC void audiod_sof_isr (uint8_t rhport, uint32_t frame_count) uint32_t const interval = 1UL << (audio->feedback.frame_shift - hs_adjust); if ( 0 == (frame_count & (interval-1)) ) { - if(tud_audio_feedback_interval_isr) tud_audio_feedback_interval_isr(i, frame_count, audio->feedback.frame_shift); + tud_audio_feedback_interval_isr(i, frame_count, audio->feedback.frame_shift); } } } diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 9c95ce1a9..0d658de7c 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -451,17 +451,17 @@ bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_req //--------------------------------------------------------------------+ #if CFG_TUD_AUDIO_ENABLE_EP_IN -TU_ATTR_WEAK bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t func_id, uint8_t ep_in, uint8_t cur_alt_setting); -TU_ATTR_WEAK bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t func_id, uint8_t ep_in, uint8_t cur_alt_setting); +bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t func_id, uint8_t ep_in, uint8_t cur_alt_setting); +bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t func_id, uint8_t ep_in, uint8_t cur_alt_setting); #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT -TU_ATTR_WEAK bool tud_audio_rx_done_pre_read_cb(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting); -TU_ATTR_WEAK bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting); +bool tud_audio_rx_done_pre_read_cb(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting); +bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting); #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -TU_ATTR_WEAK void tud_audio_fb_done_cb(uint8_t func_id); +void tud_audio_fb_done_cb(uint8_t func_id); // determined by the user itself and set by use of tud_audio_n_fb_set(). The feedback value may be determined e.g. from some fill status of some FIFO buffer. Advantage: No ISR interrupt is enabled, hence the CPU need not to handle an ISR every 1ms or 125us and thus less CPU load, disadvantage: typically a larger FIFO is needed to compensate for jitter (e.g. 8 frames), i.e. a larger delay is introduced. @@ -516,43 +516,43 @@ typedef struct { }audio_feedback_params_t; // Invoked when needed to set feedback parameters -TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param); +void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param); // Callback in ISR context, invoked periodically according to feedback endpoint bInterval. // Could be used to compute and update feedback value, should be placed in RAM if possible // frame_number : current SOF count // interval_shift: number of bit shift i.e log2(interval) from Feedback endpoint descriptor -TU_ATTR_WEAK TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift); +TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift); #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -TU_ATTR_WEAK void tud_audio_int_done_cb(uint8_t rhport); +void tud_audio_int_done_cb(uint8_t rhport); #endif // Invoked when audio set interface request received -TU_ATTR_WEAK bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request); +bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request); // Invoked when audio set interface request received which closes an EP -TU_ATTR_WEAK bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request); +bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request); // Invoked when audio class specific set request received for an EP -TU_ATTR_WEAK bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff); +bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff); // Invoked when audio class specific set request received for an interface -TU_ATTR_WEAK bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff); +bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff); // Invoked when audio class specific set request received for an entity -TU_ATTR_WEAK bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff); +bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff); // Invoked when audio class specific get request received for an EP -TU_ATTR_WEAK bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request); +bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request); // Invoked when audio class specific get request received for an interface -TU_ATTR_WEAK bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request); +bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request); // Invoked when audio class specific get request received for an entity -TU_ATTR_WEAK bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request); +bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request); //--------------------------------------------------------------------+ // Inline Functions -- cgit v1.3.1 From 8dc767fa1dd768878ed8bd8541398b0722875066 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 8 May 2024 22:31:30 +0200 Subject: Fix cycle based feedback calculation. --- src/class/audio/audio_device.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 555ecd4ea..c0a8d1d72 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -66,8 +66,10 @@ //--------------------------------------------------------------------+ // Use ring buffer if it's available, some MCUs need extra RAM requirements +// For DWC2 enable ring buffer will disable DMA (if available) #ifndef TUD_AUDIO_PREFER_RING_BUFFER - #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX + #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX || \ + defined(TUP_USBIP_DWC2) #define TUD_AUDIO_PREFER_RING_BUFFER 0 #else #define TUD_AUDIO_PREFER_RING_BUFFER 1 @@ -2347,11 +2349,11 @@ static bool audiod_set_fb_params_freq(audiod_function_t* audio, uint32_t sample_ if ((mclk_freq % sample_freq) == 0 && tu_is_power_of_two(mclk_freq / sample_freq)) { audio->feedback.compute_method = AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2; - audio->feedback.compute.power_of_2 = 16 - audio->feedback.frame_shift - tu_log2(mclk_freq / sample_freq); + audio->feedback.compute.power_of_2 = 16 - (audio->feedback.frame_shift - 1) - tu_log2(mclk_freq / sample_freq); } else if ( audio->feedback.compute_method == AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT) { - audio->feedback.compute.float_const = (float)sample_freq / mclk_freq * (1UL << (16 - audio->feedback.frame_shift)); + audio->feedback.compute.float_const = (float)sample_freq / mclk_freq * (1UL << (16 - (audio->feedback.frame_shift - 1))); } else { @@ -2411,7 +2413,7 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED: { - uint64_t fb64 = (((uint64_t) cycles) * audio->feedback.compute.fixed.sample_freq) << (16 - audio->feedback.frame_shift); + uint64_t fb64 = (((uint64_t) cycles) * audio->feedback.compute.fixed.sample_freq) << (16 - (audio->feedback.frame_shift - 1)); feedback = (uint32_t) (fb64 / audio->feedback.compute.fixed.mclk_freq); } break; -- cgit v1.3.1 From ab539895a5be8138ae60aecedac6d32a1748bffc Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 8 May 2024 23:08:47 +0200 Subject: Reorganize feedback documentation. --- src/class/audio/audio_device.h | 53 +++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 0d658de7c..5a1c51eaf 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -243,7 +243,8 @@ // Enable encoding/decodings - for these to work, support FIFOs need to be setup in appropriate numbers and size // The actual coding parameters of active AS alternate interface is parsed from the descriptors -// The item size of the FIFO is always fixed to one i.e. bytes! Furthermore, the actively used FIFO depth is reconfigured such that the depth is a multiple of the current sample size in order to avoid samples to get split up in case of a wrap in the FIFO ring buffer (depth = (max_depth / sampe_sz) * sampe_sz)! +// The item size of the FIFO is always fixed to one i.e. bytes! Furthermore, the actively used FIFO depth is reconfigured such that the depth is a multiple +// of the current sample size in order to avoid samples to get split up in case of a wrap in the FIFO ring buffer (depth = (max_depth / sample_sz) * sample_sz)! // This is important to remind in case you use DMAs! If the sample sizes changes, the DMA MUST BE RECONFIGURED just like the FIFOs for a different depth!!! // For PCM encoding/decoding @@ -447,7 +448,7 @@ static inline bool tud_audio_int_write (const audio_interru bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_request_t const * p_request, void* data, uint16_t len); //--------------------------------------------------------------------+ -// Application Callback API (weak is optional) +// Application Callback API //--------------------------------------------------------------------+ #if CFG_TUD_AUDIO_ENABLE_EP_IN @@ -464,42 +465,62 @@ bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_bytes_received, u void tud_audio_fb_done_cb(uint8_t func_id); -// determined by the user itself and set by use of tud_audio_n_fb_set(). The feedback value may be determined e.g. from some fill status of some FIFO buffer. Advantage: No ISR interrupt is enabled, hence the CPU need not to handle an ISR every 1ms or 125us and thus less CPU load, disadvantage: typically a larger FIFO is needed to compensate for jitter (e.g. 8 frames), i.e. a larger delay is introduced. - -// Feedback value is calculated within the audio driver by use of SOF interrupt. The driver needs information about the master clock f_m from which the audio sample frequency f_s is derived, f_s itself, and the cycle count of f_m at time of the SOF interrupt (e.g. by use of a hardware counter) - see tud_audio_set_fb_params(). Advantage: Reduced jitter in the feedback value computation, hence, the receive FIFO can be smaller (e.g. 2 frames) and thus a smaller delay is possible, disadvantage: higher CPU load due to SOF ISR handling every frame i.e. 1ms or 125us. This option is a great starting point to try the SOF ISR option but depending on your hardware setup (performance of the CPU) it might not work. If so, figure out why and use the next option. (The most critical point is the reading of the cycle counter value of f_m. It is read from within the SOF ISR - see: audiod_sof() -, hence, the ISR must has a high priority such that no software dependent "random" delay i.e. jitter is introduced). +// Note about feedback calculation +// +// Option 1 - AUDIO_FEEDBACK_METHOD_FIFO_COUNT +// Feedback value is calculated within the audio driver by regulating the FIFO level to half fill. +// Advantage: No ISR interrupt is enabled, hence the CPU need not to handle an ISR every 1ms or 125us and thus less CPU load, well tested +// (Windows, Linux, OSX) with a reliable result so far. +// Disadvantage: A FIFO of minimal 4 frames is needed to compensate for jitter, an average delay of 2 frames is introduced. +// +// Option 2 - AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED / AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT +// Feedback value is calculated within the audio driver by use of SOF interrupt. The driver needs information about the master clock f_m from +// which the audio sample frequency f_s is derived, f_s itself, and the cycle count of f_m at time of the SOF interrupt (e.g. by use of a hardware counter). +// See tud_audio_set_fb_params() and tud_audio_feedback_update() +// Advantage: Reduced jitter in the feedback value computation, hence, the receive FIFO can be smaller and thus a smaller delay is possible. +// Disadvantage: higher CPU load due to SOF ISR handling every frame i.e. 1ms or 125us. (The most critical point is the reading of the cycle counter value of f_m. +// It is read from within the SOF ISR - see: audiod_sof() -, hence, the ISR must has a high priority such that no software dependent "random" delay i.e. jitter is introduced). +// Long-term drift could occur since error is accumulated. +// +// Option 3 - manual +// Determined by the user itself and set by use of tud_audio_n_fb_set(). The feedback value may be determined e.g. from some fill status of some FIFO buffer. +// Advantage: No ISR interrupt is enabled, hence the CPU need not to handle an ISR every 1ms or 125us and thus less CPU load. +// Disadvantage: typically a larger FIFO is needed to compensate for jitter (e.g. 6 frames), i.e. a larger delay is introduced. -// Feedback value is determined by the user by use of SOF interrupt. The user may use tud_audio_sof_isr() which is called every SOF (of course only invoked when an alternate interface other than zero was set). The number of frames used to determine the feedback value for the currently active alternate setting can be get by tud_audio_get_fb_n_frames(). The feedback value must be set by use of tud_audio_n_fb_set(). // This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed. // // The feedback format is specified to be 16.16 for HS and 10.14 for FS devices (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). By default, -// the choice of format is left to the caller and feedback argument is sent as-is. If CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION is set, then tinyusb -// expects 16.16 format and handles the conversion to 10.14 on FS. +// the choice of format is left to the caller and feedback argument is sent as-is. If CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION is set +// then tinyusb expects 16.16 format and handles the conversion to 10.14 on FS. +// +// Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and it seems the +// driver can work with either format. // -// Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and macOS it seems the -// driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format. - // Feedback value can be determined from within the SOF ISR of the audio driver. This should reduce jitter. If the feature is used, the user can not set the feedback value. - +// // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec // Boiled down, the feedback value Ff = n_samples / (micro)frame. -// Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_m is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) +// Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 +// for high speed, f_s is the sampling frequency e.g. 48 kHz and f_m is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) // The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_m / f_s)), K) // feedback = n_cycles / n_frames * f_s / f_m in 16.16 format, where n_cycles are the number of main clock cycles within fb_n_frames - bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); -// Update feedback value with passed cycles since last time this update function is called. +// Update feedback value with passed MCLK cycles since last time this update function is called. // Typically called within tud_audio_sof_isr(). Required tud_audio_feedback_params_cb() is implemented // This function will also call tud_audio_feedback_set() // return feedback value in 16.16 for reference (0 for error) +// Example : +// binterval=3 (4ms); FS = 48kHz; MCLK = 12.288MHz +// In 4 SOF MCLK counted 49152 cycles uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles); enum { AUDIO_FEEDBACK_METHOD_DISABLED, AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED, AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT, - AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2, + AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2, // For driver internal use only AUDIO_FEEDBACK_METHOD_FIFO_COUNT }; -- cgit v1.3.1 From 0e907b49c90d53023731dd1e21bbdcb1fdb95e11 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 8 May 2024 23:17:56 +0200 Subject: Add callback to to set feedback format correction at runtime. --- src/class/audio/audio_device.c | 23 +++++++++++++---------- src/class/audio/audio_device.h | 8 ++++++-- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index c0a8d1d72..77645c412 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -329,7 +329,7 @@ typedef struct uint8_t frame_shift; // bInterval-1 in unit of frame (FS), micro-frame (HS) uint8_t compute_method; - + bool format_correction; union { uint8_t power_of_2; // pre-computed power of 2 shift float float_const; // pre-computed float constant @@ -484,6 +484,11 @@ TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, (void) alt_itf; feedback_param->method = AUDIO_FEEDBACK_METHOD_DISABLED; } + +TU_ATTR_WEAK bool tud_audio_feedback_format_correction_cb(uint8_t func_id) { + (void) func_id; + return CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION; +} #endif TU_ATTR_WEAK TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift) { @@ -1211,9 +1216,9 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP static inline bool audiod_fb_send(audiod_function_t *audio) { + bool apply_correction = TUSB_SPEED_FULL == tud_speed_get() && audio->feedback.format_correction; // Format the feedback value -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION - if ( TUSB_SPEED_FULL == tud_speed_get() ) + if (apply_correction) { uint8_t * fb = (uint8_t *) &audio->feedback.send_buf; @@ -1221,17 +1226,12 @@ static inline bool audiod_fb_send(audiod_function_t *audio) *(fb++) = (audio->feedback.value >> 2) & 0xFF; *(fb++) = (audio->feedback.value >> 10) & 0xFF; *(fb++) = (audio->feedback.value >> 18) & 0xFF; - // 4th byte is needed to work correctly with MS Windows - *fb = 0; } else { - value = audio->feedback.value; + audio->feedback.send_buf = audio->feedback.value; } -#else - audio->feedback.send_buf = audio->feedback.value; -#endif - return usbd_edpt_xfer(audio->rhport, audio->ep_fb, (uint8_t *) &audio->feedback.send_buf, 4); + return usbd_edpt_xfer(audio->rhport, audio->ep_fb, (uint8_t *) &audio->feedback.send_buf, apply_correction ? 3 : 4); } #endif @@ -2018,6 +2018,9 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * tud_audio_feedback_params_cb(func_id, alt, &fb_param); audio->feedback.compute_method = fb_param.method; + if(TUSB_SPEED_FULL == tud_speed_get()) + audio->feedback.format_correction = tud_audio_feedback_format_correction_cb(func_id); + // Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000; audio->feedback.min_value = ((fb_param.sample_freq - 1)/frame_div) << 16; diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 5a1c51eaf..ae253f49d 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -193,6 +193,7 @@ #endif // Enable/disable conversion from 16.16 to 10.14 format on full-speed devices. See tud_audio_n_fb_set(). +// Can be override by tud_audio_feedback_format_correction_cb() #ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 #endif @@ -491,8 +492,8 @@ void tud_audio_fb_done_cb(uint8_t func_id); // This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed. // // The feedback format is specified to be 16.16 for HS and 10.14 for FS devices (see Universal Serial Bus Specification Revision 2.0 5.12.4.2). By default, -// the choice of format is left to the caller and feedback argument is sent as-is. If CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION is set -// then tinyusb expects 16.16 format and handles the conversion to 10.14 on FS. +// the choice of format is left to the caller and feedback argument is sent as-is. If CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION is set or tud_audio_feedback_format_correction_cb() +// return true, then tinyusb expects 16.16 format and handles the conversion to 10.14 on FS. // // Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and it seems the // driver can work with either format. @@ -545,6 +546,9 @@ void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedba // interval_shift: number of bit shift i.e log2(interval) from Feedback endpoint descriptor TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift); +// (Full-Speed only) Callback to set feedback format correction is applied or not, +// default to CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION if not implemented. +bool tud_audio_feedback_format_correction_cb(uint8_t func_id); #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -- cgit v1.3.1 From 1cab553f4bcb6633face4f50f03192928a68f751 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 13:55:18 +0200 Subject: Format. --- src/portable/wch/dcd_ch32_usbhs.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 41c1d8c7c..68e2179e9 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -135,15 +135,12 @@ void dcd_remote_wakeup(uint8_t rhport) (void) rhport; } -void dcd_sof_enable(uint8_t rhport, bool en) +void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; - if (en) - { + if (en) { USBHSD->INT_EN |= USBHS_SOF_ACT_EN; - } - else - { + } else { USBHSD->INT_EN &= ~(USBHS_SOF_ACT_EN); } } @@ -347,6 +344,7 @@ void dcd_int_handler(uint8_t rhport) { if (rx_token == PID_SOF) { dcd_event_sof(rhport, USBHSD->FRAME_NO, true); + } else if (rx_token == PID_OUT) { uint16_t rx_len = USBHSD->RX_LEN; -- cgit v1.3.1 From ba6babf570752a28379aab51d9c27e7b9efe872d Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Thu, 9 May 2024 20:43:46 +0700 Subject: Rework ci (#2631) * add name field to usbd_class_driver_t * ci: use set matrix py script * add riscv32 and cmake support for ch32v307, fomu, gd32vf103 * update build_cmake.py to take --family --board --toolchain * separate hil test to its own workflow * move esp32 board into separated hil json * add make build to ci * remov build_make.py * build.py support esp32 board * setup toolchain support esp-idf * fix missing click * merge family in matrix build to reduce jobs * skip cifuzz since it still has issue with get_deps and click --- .github/actions/prepare_build/action.yml | 30 +++ .github/actions/setup_toolchain/action.yml | 31 +++ .../actions/setup_toolchain/download/action.yml | 29 ++ .github/workflows/build_aarch64.yml | 70 ----- .github/workflows/build_arm.yml | 57 ---- .github/workflows/build_cmake.yml | 295 ++++----------------- .github/workflows/build_esp.yml | 19 +- .github/workflows/build_family.yml | 64 +++++ .github/workflows/build_iar.yml | 4 +- .github/workflows/build_renesas.yml | 6 +- .github/workflows/build_riscv.yml | 71 ----- .github/workflows/build_win_mac.yml | 6 +- .github/workflows/ci_set_matrix.py | 51 ++++ .github/workflows/cifuzz.yml | 3 + .github/workflows/codeql-buildscript.sh | 3 +- .github/workflows/hil_test.yml | 125 +++++++++ .github/workflows/pre-commit.yml | 1 + .idea/cmake.xml | 8 +- examples/build_system/cmake/cpu/rv32i-ilp32.cmake | 19 ++ .../build_system/cmake/cpu/rv32imac-ilp32.cmake | 18 ++ .../build_system/cmake/toolchain/riscv_gcc.cmake | 21 ++ examples/build_system/make/cpu/rv32i-ilp32.mk | 13 + examples/build_system/make/cpu/rv32imac-ilp32.mk | 13 + examples/build_system/make/toolchain/riscv_gcc.mk | 20 ++ examples/device/video_capture/skip.txt | 1 - .../ch32v307/boards/ch32v307v_r1_1v0/board.cmake | 4 + .../ch32v307/boards/ch32v307v_r1_1v0/debug_uart.c | 110 -------- .../ch32v307/boards/ch32v307v_r1_1v0/debug_uart.h | 31 --- hw/bsp/ch32v307/debug_uart.c | 110 ++++++++ hw/bsp/ch32v307/debug_uart.h | 31 +++ hw/bsp/ch32v307/family.cmake | 114 ++++++++ hw/bsp/ch32v307/family.mk | 12 +- .../led_strip_rmt_ws2812/dependencies.lock | 15 -- hw/bsp/family_support.cmake | 24 +- hw/bsp/fomu/boards/fomu/board.cmake | 4 + hw/bsp/fomu/family.c | 121 +++++++++ hw/bsp/fomu/family.cmake | 91 +++++++ hw/bsp/fomu/family.mk | 9 +- hw/bsp/fomu/fomu.c | 120 --------- .../boards/sipeed_longan_nano/board.cmake | 13 + .../gd32vf103/boards/sipeed_longan_nano/board.mk | 1 - hw/bsp/gd32vf103/family.c | 4 +- hw/bsp/gd32vf103/family.cmake | 119 +++++++++ hw/bsp/gd32vf103/family.mk | 10 +- hw/bsp/lpc51/family.cmake | 1 - src/device/usbd.c | 28 +- src/device/usbd_pvt.h | 7 +- test/hil/hfp.json | 25 ++ test/hil/hil_hfp.json | 25 -- test/hil/hil_pi4.json | 37 --- test/hil/hil_test.py | 69 +++-- test/hil/pi4.json | 27 ++ test/hil/pi4_esp32.json | 14 + tools/build.py | 177 +++++++++++++ tools/build_board.py | 69 ----- tools/build_cmake.py | 105 -------- tools/build_make.py | 80 ------ tools/get_deps.py | 54 ++-- 58 files changed, 1482 insertions(+), 1157 deletions(-) create mode 100644 .github/actions/prepare_build/action.yml create mode 100644 .github/actions/setup_toolchain/action.yml create mode 100644 .github/actions/setup_toolchain/download/action.yml delete mode 100644 .github/workflows/build_aarch64.yml delete mode 100644 .github/workflows/build_arm.yml create mode 100644 .github/workflows/build_family.yml delete mode 100644 .github/workflows/build_riscv.yml create mode 100644 .github/workflows/ci_set_matrix.py create mode 100644 .github/workflows/hil_test.yml create mode 100644 examples/build_system/cmake/cpu/rv32i-ilp32.cmake create mode 100644 examples/build_system/cmake/cpu/rv32imac-ilp32.cmake create mode 100644 examples/build_system/cmake/toolchain/riscv_gcc.cmake create mode 100644 examples/build_system/make/cpu/rv32i-ilp32.mk create mode 100644 examples/build_system/make/cpu/rv32imac-ilp32.mk create mode 100644 examples/build_system/make/toolchain/riscv_gcc.mk create mode 100644 hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/board.cmake delete mode 100644 hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/debug_uart.c delete mode 100644 hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/debug_uart.h create mode 100644 hw/bsp/ch32v307/debug_uart.c create mode 100644 hw/bsp/ch32v307/debug_uart.h create mode 100644 hw/bsp/ch32v307/family.cmake delete mode 100644 hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/dependencies.lock create mode 100644 hw/bsp/fomu/boards/fomu/board.cmake create mode 100644 hw/bsp/fomu/family.c create mode 100644 hw/bsp/fomu/family.cmake delete mode 100644 hw/bsp/fomu/fomu.c create mode 100644 hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.cmake create mode 100644 hw/bsp/gd32vf103/family.cmake create mode 100644 test/hil/hfp.json delete mode 100644 test/hil/hil_hfp.json delete mode 100644 test/hil/hil_pi4.json create mode 100644 test/hil/pi4.json create mode 100644 test/hil/pi4_esp32.json create mode 100644 tools/build.py delete mode 100644 tools/build_board.py delete mode 100644 tools/build_cmake.py delete mode 100644 tools/build_make.py diff --git a/.github/actions/prepare_build/action.yml b/.github/actions/prepare_build/action.yml new file mode 100644 index 000000000..5f2c544c1 --- /dev/null +++ b/.github/actions/prepare_build/action.yml @@ -0,0 +1,30 @@ +name: Prepare to build + +inputs: + family: + required: true + type: string + +runs: + using: "composite" + steps: + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Checkout pico-sdk for rp2040 + if: contains(inputs.family, 'rp2040') + uses: actions/checkout@v4 + with: + repository: raspberrypi/pico-sdk + ref: develop + path: pico-sdk + + - name: Get Dependencies + run: | + sudo apt install -y ninja-build + pip install click + python3 tools/get_deps.py ${{ inputs.family }} + echo >> $GITHUB_ENV "PICO_SDK_PATH=$GITHUB_WORKSPACE/pico-sdk" + shell: bash diff --git a/.github/actions/setup_toolchain/action.yml b/.github/actions/setup_toolchain/action.yml new file mode 100644 index 000000000..b59ece116 --- /dev/null +++ b/.github/actions/setup_toolchain/action.yml @@ -0,0 +1,31 @@ +name: Setup Toolchain + +inputs: + toolchain: + required: true + type: string + toolchain_url: + required: false + type: string + +runs: + using: "composite" + steps: + - name: Install ARM GCC + if: inputs.toolchain == 'arm-gcc' + uses: carlosperate/arm-none-eabi-gcc-action@v1 + with: + release: '12.3.Rel1' + + - name: Pull ESP-IDF docker + if: inputs.toolchain == 'esp-idf' + run: docker pull espressif/idf:latest + shell: bash + + - name: Download Toolchain + if: >- + inputs.toolchain != 'arm-gcc' && + inputs.toolchain != 'esp-idf' + uses: ./.github/actions/setup_toolchain/download + with: + toolchain_url: ${{ inputs.toolchain_url }} diff --git a/.github/actions/setup_toolchain/download/action.yml b/.github/actions/setup_toolchain/download/action.yml new file mode 100644 index 000000000..db85e9027 --- /dev/null +++ b/.github/actions/setup_toolchain/download/action.yml @@ -0,0 +1,29 @@ +name: Download Toolchain + +inputs: + toolchain_url: + required: true + type: string + +runs: + using: "composite" + steps: + - name: Cache Toolchain + uses: actions/cache@v4 + id: cache-toolchain + with: + path: ~/cache/toolchain + key: ${{ runner.os }}-${{ inputs.toolchain_url }} + + - name: Install Toolchain + if: steps.cache-toolchain.outputs.cache-hit != 'true' + run: | + mkdir -p ~/cache/toolchain + wget --progress=dot:mega ${{ inputs.toolchain_url }} -O toolchain.tar.gz + tar -C ~/cache/toolchain -xaf toolchain.tar.gz + shell: bash + + - name: Set Toolchain Path + run: | + echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` + shell: bash diff --git a/.github/workflows/build_aarch64.yml b/.github/workflows/build_aarch64.yml deleted file mode 100644 index 237692498..000000000 --- a/.github/workflows/build_aarch64.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Build AArch64 - -on: - workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/build_aarch64.yml' - pull_request: - branches: [ master ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/build_aarch64.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - # --------------------------------------- - # Build AARCH64 family - # --------------------------------------- - build-arm: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - family: - # Alphabetical order - - 'broadcom_64bit' - steps: - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Set Toolchain URL - run: echo >> $GITHUB_ENV TOOLCHAIN_URL=https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz - - - name: Cache Toolchain - uses: actions/cache@v4 - id: cache-toolchain - with: - path: ~/cache/ - key: ${{ runner.os }}-21-11-02-${{ env.TOOLCHAIN_URL }} - - - name: Install Toolchain - if: steps.cache-toolchain.outputs.cache-hit != 'true' - run: | - mkdir -p ~/cache/toolchain - wget --progress=dot:mega $TOOLCHAIN_URL -O toolchain.tar.gz - tar -C ~/cache/toolchain -xaf toolchain.tar.gz - - - name: Set Toolchain Path - run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` - - - name: Get Dependencies - run: python3 tools/get_deps.py ${{ matrix.family }} - - - name: Build - run: python3 tools/build_make.py ${{ matrix.family }} diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml deleted file mode 100644 index 14c6d519c..000000000 --- a/.github/workflows/build_arm.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Build ARM - -on: - workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'tools/get_deps.py' - - '.github/workflows/build_arm.yml' - pull_request: - branches: [ master ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'tools/get_deps.py' - - '.github/workflows/build_arm.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - # --------------------------------------- - # Build ARM family - # --------------------------------------- - build-arm: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - family: - # Alphabetical order - - 'mm32' - steps: - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Install ARM GCC - uses: carlosperate/arm-none-eabi-gcc-action@v1 - with: - release: '11.2-2022.02' - - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Get Dependencies - run: python3 tools/get_deps.py ${{ matrix.family }} - - - name: Build - run: python3 tools/build_make.py ${{ matrix.family }} diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index c1f85ad9c..b62a0e9bd 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -1,4 +1,4 @@ -name: Build CMake +name: Build on: workflow_dispatch: @@ -8,9 +8,11 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' - - 'test/hil/**' - 'tools/get_deps.py' + - 'tools/build.py' + - '.github/actions/**' - '.github/workflows/build_cmake.yml' + - '.github/workflows/ci_set_matrix.py' pull_request: branches: [ master ] paths: @@ -18,141 +20,20 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' - - 'test/hil/**' - 'tools/get_deps.py' + - 'tools/build.py' + - '.github/actions/**' - '.github/workflows/build_cmake.yml' - + - '.github/workflows/ci_set_matrix.py' concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: - # --------------------------------------- - # Build ARM with GCC - # --------------------------------------- - arm-gcc: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - family: - # Alphabetical order - - 'broadcom_32bit' - - 'imxrt' - - 'kinetis_k kinetis_kl kinetis_k32l2' - - 'lpc11 lpc13 lpc15' - - 'lpc17 lpc18 lpc40 lpc43' - - 'lpc51 lpc54 lpc55' - - 'mcx' - - 'msp432e4' - - 'mm32' - - 'nrf' - - 'ra' - - 'rp2040' - - 'samd11 samd21 saml2x samd5x_e5x samg' - - 'stm32f0' - - 'stm32f1' - - 'stm32f2' - - 'stm32f3' - - 'stm32f4' - - 'stm32f7' - - 'stm32g0' - - 'stm32g4' - - 'stm32h5' - - 'stm32h7' - - 'stm32l4' - - 'stm32u5' - - 'stm32wb' - - 'tm4c' - - 'xmc4000' - steps: - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Install ARM GCC - uses: carlosperate/arm-none-eabi-gcc-action@v1 - with: - release: '12.3.Rel1' - - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Checkout pico-sdk for rp2040 - if: matrix.family == 'rp2040' - uses: actions/checkout@v4 - with: - repository: raspberrypi/pico-sdk - ref: develop - path: pico-sdk - - - name: Get Dependencies - run: | - sudo apt install -y ninja-build - python3 tools/get_deps.py ${{ matrix.family }} - - - name: Build - run: python tools/build_cmake.py ${{ matrix.family }} - env: - PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk - - - name: Upload Artifacts for Hardware Testing (rp2040) - if: contains(matrix.family, 'rp2040') && github.repository_owner == 'hathach' - uses: actions/upload-artifact@v4 - with: - name: raspberry_pi_pico - path: | - cmake-build/cmake-build-raspberry_pi_pico/*/*/*.elf - - - name: Upload Artifacts for Hardware Testing (nRF) - if: contains(matrix.family, 'nrf') && github.repository_owner == 'hathach' - uses: actions/upload-artifact@v4 - with: - name: feather_nrf52840_express - path: | - cmake-build/cmake-build-feather_nrf52840_express/*/*/*.elf - - - name: Upload Artifacts for Hardware Testing (samd51) - if: contains(matrix.family, 'samd5x_e5x') && github.repository_owner == 'hathach' - uses: actions/upload-artifact@v4 - with: - name: itsybitsy_m4 - path: | - cmake-build/cmake-build-itsybitsy_m4/*/*/*.bin - - # --------------------------------------- - # Build ARM with Clang - # --------------------------------------- - arm-clang: + set-matrix: runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - family: - # Alphabetical order - - 'imxrt' - - 'kinetis_k kinetis_kl' - - 'lpc17 lpc18 lpc40 lpc43' - - 'lpc54 lpc55' - #- 'mcx' not working with gcc anymore, need to fix this first - - 'nrf' - #- 'ra' port later - #- 'rp2040' port later - - 'samd21' - - 'samd5x_e5x' - - 'stm32f0' - - 'stm32f1' - - 'stm32f2' - - 'stm32f3' - - 'stm32f4' - - 'stm32f7' - - 'stm32g0' - - 'stm32g4' - - 'stm32h5' - - 'stm32h7' - - 'stm32l4' - - 'stm32u5' + outputs: + json: ${{ steps.set-matrix-json.outputs.matrix }} steps: - name: Setup Python uses: actions/setup-python@v5 @@ -162,137 +43,51 @@ jobs: - name: Checkout TinyUSB uses: actions/checkout@v4 - - name: Checkout pico-sdk for rp2040 - if: matrix.family == 'rp2040' - uses: actions/checkout@v4 - with: - repository: raspberrypi/pico-sdk - ref: develop - path: pico-sdk - - - name: Set Toolchain URL - run: echo >> $GITHUB_ENV TOOLCHAIN_URL=https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-17.0.1/LLVMEmbeddedToolchainForArm-17.0.1-Linux-x86_64.tar.xz - - - name: Cache Toolchain - uses: actions/cache@v4 - id: cache-toolchain - with: - path: ~/cache/ - key: ${{ runner.os }}-24-04-17-${{ env.TOOLCHAIN_URL }} - - - name: Install Toolchain - if: steps.cache-toolchain.outputs.cache-hit != 'true' - run: | - mkdir -p ~/cache/toolchain - wget --progress=dot:mega $TOOLCHAIN_URL -O toolchain.tar.xz - tar -C ~/cache/toolchain -xaf toolchain.tar.xz - - - name: Prepare to build + - name: Generate matrix json + id: set-matrix-json run: | - echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` - sudo apt install -y ninja-build - python3 tools/get_deps.py ${{ matrix.family }} - - - name: Build - run: python tools/build_cmake.py ${{ matrix.family }} -DTOOLCHAIN=clang - env: - PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk + MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py) + echo "matrix=$MATRIX_JSON" + echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT # --------------------------------------- - # Build MSP430 with GCC + # Build CMake # --------------------------------------- - msp430-gcc: - runs-on: ubuntu-latest + cmake: + needs: set-matrix + uses: ./.github/workflows/build_family.yml strategy: fail-fast: false matrix: - family: - # Alphabetical order - - 'msp430' - steps: - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Set Toolchain URL - run: echo >> $GITHUB_ENV TOOLCHAIN_URL=http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2 - - - name: Cache Toolchain - uses: actions/cache@v4 - id: cache-toolchain - with: - path: ~/cache/ - key: ${{ runner.os }}-24-04-17-${{ env.TOOLCHAIN_URL }} - - - name: Install Toolchain - if: steps.cache-toolchain.outputs.cache-hit != 'true' - run: | - mkdir -p ~/cache/toolchain - wget --progress=dot:mega $TOOLCHAIN_URL -O toolchain.tar.bz2 - tar -C ~/cache/toolchain -xaf toolchain.tar.bz2 - - - name: Prepare to build - run: | - echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` - sudo apt install -y ninja-build - python3 tools/get_deps.py ${{ matrix.family }} - - - name: Build - run: python tools/build_cmake.py ${{ matrix.family }} + toolchain: + - 'aarch64-gcc' + - 'arm-clang' + - 'arm-gcc' + - 'msp430-gcc' + - 'riscv-gcc' + with: + build-system: 'cmake' + toolchain: ${{ matrix.toolchain }} + toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} + build-family: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} # --------------------------------------- - # Hardware in the loop (HIL) - # Current self-hosted instance is running on an RPI4. For attached hardware checkout hil_pi4.json + # Build Make # --------------------------------------- - hil-test: - # run only with hathach's commit due to limited resource on RPI4 - if: github.repository_owner == 'hathach' - needs: arm-gcc - runs-on: [self-hosted, rp2040, nrf52840, hardware-in-the-loop] + make: + needs: set-matrix + uses: ./.github/workflows/build_family.yml strategy: fail-fast: false matrix: - board: - - 'feather_nrf52840_express' - - 'itsybitsy_m4' - - 'raspberry_pi_pico' - steps: - - name: Clean workspace - run: | - echo "Cleaning up previous run" - rm -rf "${{ github.workspace }}" - mkdir -p "${{ github.workspace }}" - - # USB bus on rpi4 is not stable, reset it before testing - - name: Reset USB bus - run: | - lsusb - lsusb -t - # reset VIA Labs 2.0 hub - sudo usbreset 001/002 - - # legacy code - #for port in $(lspci | grep USB | cut -d' ' -f1); do - # echo -n "0000:${port}"| sudo tee /sys/bus/pci/drivers/xhci_hcd/unbind; - # sleep 0.1; - # echo -n "0000:${port}" | sudo tee /sys/bus/pci/drivers/xhci_hcd/bind; - #done - - - name: Checkout test/hil - uses: actions/checkout@v4 - with: - sparse-checkout: test/hil - - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - name: ${{ matrix.board }} - path: cmake-build/cmake-build-${{ matrix.board }} - - - name: Test on actual hardware - run: | - python3 test/hil/hil_test.py --board ${{ matrix.board }} hil_pi4.json + toolchain: + - 'aarch64-gcc' + #- 'arm-clang' + - 'arm-gcc' + - 'msp430-gcc' + - 'riscv-gcc' + with: + build-system: 'make' + toolchain: ${{ matrix.toolchain }} + toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} + build-family: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 4108a58a5..66fa8548e 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -41,14 +41,16 @@ jobs: with: python-version: '3.x' - - name: Pull ESP-IDF docker - run: docker pull espressif/idf:latest - - name: Checkout TinyUSB uses: actions/checkout@v4 + - name: Setup Toolchain + uses: ./.github/actions/setup_toolchain + with: + toolchain: 'esp-idf' + - name: Build - run: docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python3 tools/build_esp32.py ${{ matrix.board }} + run: docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python3 tools/build.py -b ${{ matrix.board }} - name: Upload Artifacts for Hardware Testing if: matrix.board == 'espressif_s3_devkitm' && github.repository_owner == 'hathach' @@ -91,13 +93,6 @@ jobs: # reset VIA Labs 2.0 hub sudo usbreset 001/002 - # legacy code - #for port in $(lspci | grep USB | cut -d' ' -f1); do - # echo -n "0000:${port}"| sudo tee /sys/bus/pci/drivers/xhci_hcd/unbind; - # sleep 0.1; - # echo -n "0000:${port}" | sudo tee /sys/bus/pci/drivers/xhci_hcd/bind; - #done - - name: Checkout test/hil uses: actions/checkout@v4 with: @@ -111,4 +106,4 @@ jobs: - name: Test on actual hardware run: | - python3 test/hil/hil_test.py --board ${{ matrix.board }} hil_pi4.json + python3 test/hil/hil_test.py --board ${{ matrix.board }} pi4_esp32.json diff --git a/.github/workflows/build_family.yml b/.github/workflows/build_family.yml new file mode 100644 index 000000000..2e89267a3 --- /dev/null +++ b/.github/workflows/build_family.yml @@ -0,0 +1,64 @@ +name: Build family + +on: + workflow_call: + inputs: + build-system: + required: true + type: string + toolchain: + required: true + type: string + toolchain_url: + required: true + type: string + build-family: + required: true + type: string + +jobs: + family: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + family: ${{ fromJSON(inputs.build-family) }} + steps: + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Setup Toolchain + uses: ./.github/actions/setup_toolchain + with: + toolchain: ${{ inputs.toolchain }} + toolchain_url: ${{ inputs.toolchain_url }} + + - name: Checkout pico-sdk for rp2040 + if: contains(matrix.family, 'rp2040') + uses: actions/checkout@v4 + with: + repository: raspberrypi/pico-sdk + ref: develop + path: pico-sdk + + - name: Get Dependencies + run: | + sudo apt install -y ninja-build + pip install click + python3 tools/get_deps.py ${{ matrix.family }} + + - name: Build + run: | + OPTION="" + if [[ "${{ inputs.toolchain }}" == *"clang"* ]]; then + OPTION="--toolchain clang" + fi + echo "OPTION=$OPTION" + python tools/build.py -s ${{ inputs.build-system }} $OPTION ${{ matrix.family }} + env: + PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk diff --git a/.github/workflows/build_iar.yml b/.github/workflows/build_iar.yml index 6b1493a97..c4a7f96b7 100644 --- a/.github/workflows/build_iar.yml +++ b/.github/workflows/build_iar.yml @@ -52,8 +52,8 @@ jobs: run: python3 tools/get_deps.py ${{ matrix.family }} - name: Build - run: python3 tools/build_cmake.py ${{ matrix.family }} -DTOOLCHAIN=iar + run: python3 tools/build.py --toolchain iar ${{ matrix.family }} - name: Test on actual hardware (hardware in the loop) run: | - python3 test/hil/hil_test.py hil_hfp.json + python3 test/hil/hil_test.py hfp.json diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml index fbc12d285..8c83bdbbf 100644 --- a/.github/workflows/build_renesas.yml +++ b/.github/workflows/build_renesas.yml @@ -64,7 +64,9 @@ jobs: run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` - name: Get Dependencies - run: python3 tools/get_deps.py ${{ matrix.family }} + run: | + pip install click + python3 tools/get_deps.py ${{ matrix.family }} - name: Build - run: python3 tools/build_make.py ${{ matrix.family }} + run: python3 tools/build.py -s make ${{ matrix.family }} diff --git a/.github/workflows/build_riscv.yml b/.github/workflows/build_riscv.yml deleted file mode 100644 index 7f5031ff1..000000000 --- a/.github/workflows/build_riscv.yml +++ /dev/null @@ -1,71 +0,0 @@ -name: Build RISC-V - -on: - workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'tools/get_deps.py' - - '.github/workflows/build_riscv.yml' - pull_request: - branches: [ master ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'tools/get_deps.py' - - '.github/workflows/build_riscv.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build-riscv: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - family: - # Alphabetical order - - 'ch32v307' - - 'fomu' - - 'gd32vf103' - steps: - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Set Toolchain URL - run: echo >> $GITHUB_ENV TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v10.1.0-1.1/xpack-riscv-none-embed-gcc-10.1.0-1.1-linux-x64.tar.gz - - - name: Cache Toolchain - uses: actions/cache@v4 - id: cache-toolchain - with: - path: ~/cache/ - key: ${{ runner.os }}-21-03-04-${{ env.TOOLCHAIN_URL }} - - - name: Install Toolchain - if: steps.cache-toolchain.outputs.cache-hit != 'true' - run: | - mkdir -p ~/cache/toolchain - wget --progress=dot:mega $TOOLCHAIN_URL -O toolchain.tar.gz - tar -C ~/cache/toolchain -xaf toolchain.tar.gz - - - name: Set Toolchain Path - run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` - - - name: Get Dependencies - run: python3 tools/get_deps.py ${{ matrix.family }} - - - name: Build - run: python3 tools/build_make.py ${{ matrix.family }} diff --git a/.github/workflows/build_win_mac.yml b/.github/workflows/build_win_mac.yml index b33b5b593..35328aa32 100644 --- a/.github/workflows/build_win_mac.yml +++ b/.github/workflows/build_win_mac.yml @@ -48,7 +48,9 @@ jobs: uses: actions/checkout@v4 - name: Get Dependencies - run: python3 tools/get_deps.py stm32f4 + run: | + pip install click + python3 tools/get_deps.py stm32f4 - name: Build - run: python3 tools/build_make.py stm32f4 stm32f411disco + run: python3 tools/build.py -s make stm32f2 diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py new file mode 100644 index 000000000..2a17be6a1 --- /dev/null +++ b/.github/workflows/ci_set_matrix.py @@ -0,0 +1,51 @@ +import json + +# toolchain, url +toolchain_list = { + "aarch64-gcc": "https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz", + "arm-clang": "https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-17.0.1/LLVMEmbeddedToolchainForArm-17.0.1-Linux-x86_64.tar.xz", + "arm-gcc": "", + "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", + "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v10.1.0-1.1/xpack-riscv-none-embed-gcc-10.1.0-1.1-linux-x64.tar.gz", +} + +# family: [supported toolchain] +family_list = { + "broadcom_32bit": ["arm-gcc"], + "broadcom_64bit": ["aarch64-gcc"], + "ch32v307 fomu gd32vf103": ["riscv-gcc"], + "imxrt": ["arm-gcc", "arm-clang"], + "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"], + "lpc11 lpc13 lpc15": ["arm-gcc"], + "lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"], + "lpc51 lpc54 lpc55": ["arm-gcc", "arm-clang"], + "mcx": ["arm-gcc"], + "mm32": ["arm-gcc"], + "msp430": ["msp430-gcc"], + "msp432e4 tm4c": ["arm-gcc"], + "nrf": ["arm-gcc", "arm-clang"], + "ra": ["arm-gcc"], + "rp2040": ["arm-gcc"], + "samd11 samd21 saml2x": ["arm-gcc", "arm-clang"], + "samd5x_e5x samg": ["arm-gcc", "arm-clang"], + "stm32f0 stm32f1 stm32f2 stm32f3": ["arm-gcc", "arm-clang"], + "stm32f4": ["arm-gcc", "arm-clang"], + "stm32f7": ["arm-gcc", "arm-clang"], + "stm32g0 stm32g4 stm32h5": ["arm-gcc", "arm-clang"], + "stm32h7": ["arm-gcc", "arm-clang"], + "stm32l4 stm32u5 stm32wb": ["arm-gcc", "arm-clang"], + "xmc4000": ["arm-gcc"], +} + + +def set_matrix_json(): + matrix = {} + for toolchain in toolchain_list.keys(): + filtered_families = [family for family, supported_toolchain in family_list.items() if + toolchain in supported_toolchain] + matrix[toolchain] = {"family": filtered_families, "toolchain_url": toolchain_list[toolchain]} + print(json.dumps(matrix)) + + +if __name__ == '__main__': + set_matrix_json() diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 5dc0f2764..faa0f911c 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -12,6 +12,7 @@ on: - '**.h' jobs: Fuzzing: + if: false runs-on: ubuntu-latest steps: - name: Build Fuzzers @@ -20,12 +21,14 @@ jobs: with: oss-fuzz-project-name: 'tinyusb' language: c++ + - name: Run Fuzzers uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master with: oss-fuzz-project-name: 'tinyusb' language: c++ fuzz-seconds: 600 + - name: Upload Crash uses: actions/upload-artifact@v4 if: failure() && steps.build.outcome == 'success' diff --git a/.github/workflows/codeql-buildscript.sh b/.github/workflows/codeql-buildscript.sh index 35e029922..272b55d22 100644 --- a/.github/workflows/codeql-buildscript.sh +++ b/.github/workflows/codeql-buildscript.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash FAMILY=stm32l4 +pip install click python3 tools/get_deps.py $FAMILY -python3 tools/build_make.py $FAMILY +python3 tools/build.py -s make $FAMILY diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml new file mode 100644 index 000000000..024ab969d --- /dev/null +++ b/.github/workflows/hil_test.yml @@ -0,0 +1,125 @@ +name: Hardware Test + +on: + workflow_dispatch: + push: + paths: + - 'src/**' + - 'examples/**' + - 'lib/**' + - 'hw/**' + - 'test/hil/**' + - 'tools/get_deps.py' + - '.github/actions/**' + - '.github/workflows/hil_test.yml' + pull_request: + branches: [ master ] + paths: + - 'src/**' + - 'examples/**' + - 'lib/**' + - 'hw/**' + - 'test/hil/**' + - 'tools/get_deps.py' + - '.github/actions/**' + - '.github/workflows/hil_test.yml' +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + build: + if: github.repository_owner == 'hathach' + runs-on: ubuntu-latest + outputs: + BOARD_LIST: ${{ steps.parse_hil_json.outputs.BOARD_LIST }} + steps: + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install ARM GCC + uses: carlosperate/arm-none-eabi-gcc-action@v1 + with: + release: '12.3.Rel1' + + - name: Parse HIL json + id: parse_hil_json + run: | + sudo apt install -y jq + BOARD_LIST=$(jq -r '.boards[] | "-b " + .name' test/hil/pi4.json | tr '\n' ' ') + echo "BOARD_LIST=$BOARD_LIST" + echo >> $GITHUB_ENV "BOARD_LIST=$BOARD_LIST" + echo >> $GITHUB_OUTPUT "BOARD_LIST=$BOARD_LIST" + + - name: Checkout pico-sdk for rp2040 + uses: actions/checkout@v4 + with: + repository: raspberrypi/pico-sdk + ref: develop + path: pico-sdk + + - name: Get Dependencies + run: | + pip install click + sudo apt install -y ninja-build + python3 tools/get_deps.py $BOARD_LIST + + - name: Build + run: | + python tools/build.py $BOARD_LIST + env: + PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk + + - name: Upload Artifacts for Hardware Testing + uses: actions/upload-artifact@v4 + with: + name: hil_pi4 + path: | + cmake-build/cmake-build-*/*/*/*.elf + cmake-build/cmake-build-*/*/*/*.bin + + # --------------------------------------- + # Hardware in the loop (HIL) + # Current self-hosted instance is running on an RPI4. For attached hardware checkout hil_pi4.json + # --------------------------------------- + hil-pi4: + if: github.repository_owner == 'hathach' + needs: build + runs-on: [self-hosted, rp2040, nrf52840, hardware-in-the-loop] + env: + BOARD_LIST: ${{ needs.build.outputs.BOARD_LIST }} + steps: + - name: Clean workspace + run: | + echo "Cleaning up previous run" + rm -rf "${{ github.workspace }}" + mkdir -p "${{ github.workspace }}" + + # USB bus on rpi4 is not stable, reset it before testing + - name: Reset USB bus + run: | + lsusb + lsusb -t + # reset VIA Labs 2.0 hub + sudo usbreset 001/002 + + - name: Checkout TinyUSB + uses: actions/checkout@v4 + with: + sparse-checkout: test/hil + + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + name: hil_pi4 + path: cmake-build + + - name: Test on actual hardware + run: | + echo "BOARD_LIST=$BOARD_LIST" + python3 test/hil/hil_test.py $BOARD_LIST pi4.json diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index e36259daa..6b3151702 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -38,6 +38,7 @@ jobs: - name: Build Fuzzer run: | + pip install click export CC=clang export CXX=clang++ fuzz_harness=$(ls -d test/fuzz/device/*/) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 0e2ca61e4..bb13a0466 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -117,7 +117,7 @@ - + @@ -125,7 +125,11 @@ - + + + + + \ No newline at end of file diff --git a/examples/build_system/cmake/cpu/rv32i-ilp32.cmake b/examples/build_system/cmake/cpu/rv32i-ilp32.cmake new file mode 100644 index 000000000..b4889e6ff --- /dev/null +++ b/examples/build_system/cmake/cpu/rv32i-ilp32.cmake @@ -0,0 +1,19 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -march=rv32i + -mabi=ilp32 + ) + set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + -march=rv32i + -mabi=ilp32 + ) + set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + message(FATAL_ERROR "IAR not supported") + set(FREERTOS_PORT IAR_RISC_V CACHE INTERNAL "") + +endif () diff --git a/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake b/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake new file mode 100644 index 000000000..dd1bc0af7 --- /dev/null +++ b/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake @@ -0,0 +1,18 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -march=rv32imac + -mabi=ilp32 + ) + set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + -march=rv32imac + -mabi=ilp32 + ) + set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + message(FATAL_ERROR "IAR not supported") + set(FREERTOS_PORT IAR_RISC_V CACHE INTERNAL "") +endif () diff --git a/examples/build_system/cmake/toolchain/riscv_gcc.cmake b/examples/build_system/cmake/toolchain/riscv_gcc.cmake new file mode 100644 index 000000000..904b27294 --- /dev/null +++ b/examples/build_system/cmake/toolchain/riscv_gcc.cmake @@ -0,0 +1,21 @@ +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER "riscv-none-embed-gcc") +endif () + +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER "riscv-none-embed-g++") +endif () + +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +set(CMAKE_SIZE "riscv-none-embed-size" CACHE FILEPATH "") +set(CMAKE_OBJCOPY "riscv-none-embed-objcopy" CACHE FILEPATH "") +set(CMAKE_OBJDUMP "riscv-none-embed-objdump" CACHE FILEPATH "") + +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) + +get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) +if (IS_IN_TRY_COMPILE) + set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") + set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") + cmake_print_variables(CMAKE_C_LINK_FLAGS) +endif () diff --git a/examples/build_system/make/cpu/rv32i-ilp32.mk b/examples/build_system/make/cpu/rv32i-ilp32.mk new file mode 100644 index 000000000..a465baf4c --- /dev/null +++ b/examples/build_system/make/cpu/rv32i-ilp32.mk @@ -0,0 +1,13 @@ +ifeq ($(TOOLCHAIN),gcc) + CFLAGS += \ + -march=rv32i \ + -mabi=ilp32 \ + +else ifeq ($(TOOLCHAIN),iar) + #CFLAGS += --cpu cortex-a53 + #ASFLAGS += --cpu cortex-a53 + +endif + +# For freeRTOS port source +FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V diff --git a/examples/build_system/make/cpu/rv32imac-ilp32.mk b/examples/build_system/make/cpu/rv32imac-ilp32.mk new file mode 100644 index 000000000..2b6493e48 --- /dev/null +++ b/examples/build_system/make/cpu/rv32imac-ilp32.mk @@ -0,0 +1,13 @@ +ifeq ($(TOOLCHAIN),gcc) + CFLAGS += \ + -march=rv32imac \ + -mabi=ilp32 \ + +else ifeq ($(TOOLCHAIN),iar) + #CFLAGS += --cpu cortex-a53 + #ASFLAGS += --cpu cortex-a53 + +endif + +# For freeRTOS port source +FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V diff --git a/examples/build_system/make/toolchain/riscv_gcc.mk b/examples/build_system/make/toolchain/riscv_gcc.mk new file mode 100644 index 000000000..843aff38c --- /dev/null +++ b/examples/build_system/make/toolchain/riscv_gcc.mk @@ -0,0 +1,20 @@ +# makefile for arm gcc toolchain + +# Can be set by family, default to ARM GCC +CROSS_COMPILE ?= riscv-none-embed- + +CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +AS = $(CC) -x assembler-with-cpp +LD = $(CC) + +GDB = $(CROSS_COMPILE)gdb +OBJCOPY = $(CROSS_COMPILE)objcopy +SIZE = $(CROSS_COMPILE)size + +CFLAGS += \ + -fsingle-precision-constant \ + +LIBS += -lgcc -lm -lnosys + +include ${TOP}/examples/build_system/make/toolchain/gcc_common.mk diff --git a/examples/device/video_capture/skip.txt b/examples/device/video_capture/skip.txt index db64cc639..5898664a2 100644 --- a/examples/device/video_capture/skip.txt +++ b/examples/device/video_capture/skip.txt @@ -1,4 +1,3 @@ mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 -family:espressif diff --git a/hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/board.cmake b/hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/board.cmake new file mode 100644 index 000000000..9f5682042 --- /dev/null +++ b/hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/board.cmake @@ -0,0 +1,4 @@ +function(update_board TARGET) +# target_compile_definitions(${TARGET} PUBLIC +# ) +endfunction() diff --git a/hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/debug_uart.c b/hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/debug_uart.c deleted file mode 100644 index db3551ca7..000000000 --- a/hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/debug_uart.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2022 Greg Davill - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "debug_uart.h" -#include - - -#define UART_RINGBUFFER_SIZE_TX 64 -#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1) - -static char tx_buf[UART_RINGBUFFER_SIZE_TX]; -static unsigned int tx_produce; -static volatile unsigned int tx_consume; - -void USART1_IRQHandler(void) __attribute__((naked)); -void USART1_IRQHandler(void) { - __asm volatile ("call USART1_IRQHandler_impl; mret"); -} - -__attribute__((used)) void USART1_IRQHandler_impl(void) -{ - if(USART_GetITStatus(USART1, USART_IT_TC) != RESET) - { - USART_ClearITPendingBit(USART1, USART_IT_TC); - - if(tx_consume != tx_produce) { - USART_SendData(USART1, tx_buf[tx_consume]); - tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; - } - } - -} - -void uart_write(char c) -{ - unsigned int tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX; - - NVIC_DisableIRQ(USART1_IRQn); - if((tx_consume != tx_produce) || (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)) { - tx_buf[tx_produce] = c; - tx_produce = tx_produce_next; - } else { - USART_SendData(USART1, c); - } - NVIC_EnableIRQ(USART1_IRQn); -} - - -void uart_sync(void) -{ - while(tx_consume != tx_produce); -} - - -void usart_printf_init(uint32_t baudrate) -{ - GPIO_InitTypeDef GPIO_InitStructure; - USART_InitTypeDef USART_InitStructure; - - tx_produce = 0; - tx_consume = 0; - - RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); - - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - USART_InitStructure.USART_BaudRate = baudrate; - USART_InitStructure.USART_WordLength = USART_WordLength_8b; - USART_InitStructure.USART_StopBits = USART_StopBits_1; - USART_InitStructure.USART_Parity = USART_Parity_No; - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = USART_Mode_Tx; - - USART_Init(USART1, &USART_InitStructure); - USART_ITConfig(USART1, USART_IT_TC, ENABLE); - USART_Cmd(USART1, ENABLE); - - NVIC_InitTypeDef NVIC_InitStructure = { 0 }; - NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); -} diff --git a/hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/debug_uart.h b/hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/debug_uart.h deleted file mode 100644 index a7e070585..000000000 --- a/hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/debug_uart.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2022 Greg Davill - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include - -void uart_write(char c); -void uart_sync(void); -void usart_printf_init(uint32_t baudrate); diff --git a/hw/bsp/ch32v307/debug_uart.c b/hw/bsp/ch32v307/debug_uart.c new file mode 100644 index 000000000..db3551ca7 --- /dev/null +++ b/hw/bsp/ch32v307/debug_uart.c @@ -0,0 +1,110 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Greg Davill + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "debug_uart.h" +#include + + +#define UART_RINGBUFFER_SIZE_TX 64 +#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1) + +static char tx_buf[UART_RINGBUFFER_SIZE_TX]; +static unsigned int tx_produce; +static volatile unsigned int tx_consume; + +void USART1_IRQHandler(void) __attribute__((naked)); +void USART1_IRQHandler(void) { + __asm volatile ("call USART1_IRQHandler_impl; mret"); +} + +__attribute__((used)) void USART1_IRQHandler_impl(void) +{ + if(USART_GetITStatus(USART1, USART_IT_TC) != RESET) + { + USART_ClearITPendingBit(USART1, USART_IT_TC); + + if(tx_consume != tx_produce) { + USART_SendData(USART1, tx_buf[tx_consume]); + tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; + } + } + +} + +void uart_write(char c) +{ + unsigned int tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX; + + NVIC_DisableIRQ(USART1_IRQn); + if((tx_consume != tx_produce) || (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)) { + tx_buf[tx_produce] = c; + tx_produce = tx_produce_next; + } else { + USART_SendData(USART1, c); + } + NVIC_EnableIRQ(USART1_IRQn); +} + + +void uart_sync(void) +{ + while(tx_consume != tx_produce); +} + + +void usart_printf_init(uint32_t baudrate) +{ + GPIO_InitTypeDef GPIO_InitStructure; + USART_InitTypeDef USART_InitStructure; + + tx_produce = 0; + tx_consume = 0; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + USART_InitStructure.USART_BaudRate = baudrate; + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_Parity = USART_Parity_No; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Tx; + + USART_Init(USART1, &USART_InitStructure); + USART_ITConfig(USART1, USART_IT_TC, ENABLE); + USART_Cmd(USART1, ENABLE); + + NVIC_InitTypeDef NVIC_InitStructure = { 0 }; + NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); +} diff --git a/hw/bsp/ch32v307/debug_uart.h b/hw/bsp/ch32v307/debug_uart.h new file mode 100644 index 000000000..a7e070585 --- /dev/null +++ b/hw/bsp/ch32v307/debug_uart.h @@ -0,0 +1,31 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Greg Davill + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include + +void uart_write(char c); +void uart_sync(void); +void usart_printf_init(uint32_t baudrate); diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake new file mode 100644 index 000000000..87a0f2eba --- /dev/null +++ b/hw/bsp/ch32v307/family.cmake @@ -0,0 +1,114 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v307/EVT/EXAM/SRC) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR rv32imac-ilp32 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS CH32V307 CACHE INTERNAL "") +set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") +set(OPENOCD_OPTION2 "-c wlink_reset_resume") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ch32v307.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/Startup/startup_ch32v30x_D8C.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/Core/core_riscv.c + ${SDK_DIR}/Peripheral/src/ch32v30x_gpio.c + ${SDK_DIR}/Peripheral/src/ch32v30x_misc.c + ${SDK_DIR}/Peripheral/src/ch32v30x_rcc.c + ${SDK_DIR}/Peripheral/src/ch32v30x_usart.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ch32v30x_it.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_ch32v30x.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/Peripheral/inc + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC + -msmall-data-limit=8 + -mno-save-restore + -fmessage-length=0 + -fsigned-char + ) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for MSP432E4") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/debug_uart.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_CH32V307 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/wch/dcd_ch32_usbhs.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_openocd_wch(${TARGET}) +endfunction() diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index 07e57f04c..003b90539 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -6,29 +6,28 @@ CROSS_COMPILE ?= riscv-none-embed- # Submodules CH32V307_SDK = hw/mcu/wch/ch32v307 -DEPS_SUBMODULES += $(CH32V307_SDK) # WCH-SDK paths CH32V307_SDK_SRC = $(CH32V307_SDK)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= rv32imac-ilp32 CFLAGS += \ -flto \ - -march=rv32imac \ - -mabi=ilp32 \ -msmall-data-limit=8 \ -mno-save-restore -Os \ -fmessage-length=0 \ -fsigned-char \ -ffunction-sections \ -fdata-sections \ - -nostdlib -nostartfiles \ -DCFG_TUSB_MCU=OPT_MCU_CH32V307 \ -Xlinker --gc-sections \ -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/wch/dcd_ch32_usbhs.c \ @@ -62,5 +61,6 @@ FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V # openocd binaries will be generated in riscv-openocd-wch/src # flash target ROM bootloader +OPENOCD_WCH = /home/${USER}/app/riscv-openocd-wch/src/openocd flash: $(BUILD)/$(PROJECT).elf - openocd -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "program $<" -c wlink_reset_resume -c exit + $(OPENOCD_WCH) -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "program $<" -c wlink_reset_resume -c exit diff --git a/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/dependencies.lock b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/dependencies.lock deleted file mode 100644 index 97840a153..000000000 --- a/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/dependencies.lock +++ /dev/null @@ -1,15 +0,0 @@ -dependencies: - espressif/led_strip: - component_hash: null - source: - path: /home/hathach/code/idf-extra-components/led_strip - type: local - version: 2.5.2 - idf: - component_hash: null - source: - type: idf - version: 5.1.1 -manifest_hash: 47d47762be26168b388cb0e6cbfee6b22c68d630ebf4b27a49c47c4c54191590 -target: esp32s3 -version: 1.0.0 diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index bac1ecb5f..df4f616ef 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -385,6 +385,10 @@ function(family_flash_jlink TARGET) set(JLINKEXE JLinkExe) endif () + if (NOT DEFINED JLINK_IF) + set(JLINK_IF swd) + endif () + file(GENERATE OUTPUT $/${TARGET}.jlink CONTENT "halt @@ -396,7 +400,7 @@ exit" add_custom_target(${TARGET}-jlink DEPENDS ${TARGET} - COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} -if swd -JTAGConf -1,-1 -speed auto -CommandFile $/${TARGET}.jlink + COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile $/${TARGET}.jlink ) endfunction() @@ -420,16 +424,30 @@ function(family_flash_openocd TARGET) set(OPENOCD openocd) endif () - separate_arguments(OPENOCD_OPTION_LIST UNIX_COMMAND ${OPENOCD_OPTION}) + if (NOT DEFINED OPENOCD_OPTION2) + set(OPENOCD_OPTION2 "") + endif () + + separate_arguments(OPTION_LIST UNIX_COMMAND ${OPENOCD_OPTION}) + separate_arguments(OPTION_LIST2 UNIX_COMMAND ${OPENOCD_OPTION2}) # note skip verify since it has issue with rp2040 add_custom_target(${TARGET}-openocd DEPENDS ${TARGET} - COMMAND ${OPENOCD} ${OPENOCD_OPTION_LIST} -c "program $ reset exit" + COMMAND ${OPENOCD} ${OPTION_LIST} -c "program $ reset" ${OPTION_LIST2} -c exit VERBATIM ) endfunction() +# Add flash openocd-wch target +function(family_flash_openocd_wch TARGET) + if (NOT DEFINED OPENOCD) + set(OPENOCD $ENV{HOME}/app/riscv-openocd-wch/src/openocd) + endif () + + family_flash_openocd(${TARGET}) +endfunction() + # Add flash pycod target function(family_flash_pyocd TARGET) if (NOT DEFINED PYOC) diff --git a/hw/bsp/fomu/boards/fomu/board.cmake b/hw/bsp/fomu/boards/fomu/board.cmake new file mode 100644 index 000000000..9f5682042 --- /dev/null +++ b/hw/bsp/fomu/boards/fomu/board.cmake @@ -0,0 +1,4 @@ +function(update_board TARGET) +# target_compile_definitions(${TARGET} PUBLIC +# ) +endfunction() diff --git a/hw/bsp/fomu/family.c b/hw/bsp/fomu/family.c new file mode 100644 index 000000000..ccf2b12f4 --- /dev/null +++ b/hw/bsp/fomu/family.c @@ -0,0 +1,121 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include +#include +#include "csr.h" +#include "irq.h" + +#include "bsp/board_api.h" + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void fomu_error(uint32_t line) +{ + (void)line; + TU_BREAKPOINT(); +} + +volatile uint32_t system_ticks = 0; +static void timer_init(void) +{ + int t; + + timer0_en_write(0); + t = CONFIG_CLOCK_FREQUENCY / 1000; // 1000 kHz tick + timer0_reload_write(t); + timer0_load_write(t); + timer0_en_write(1); + timer0_ev_enable_write(1); + timer0_ev_pending_write(1); + irq_setmask(irq_getmask() | (1 << TIMER0_INTERRUPT)); +} + +void isr(void) +{ + unsigned int irqs; + + irqs = irq_pending() & irq_getmask(); + +#if CFG_TUD_ENABLED + if (irqs & (1 << USB_INTERRUPT)) { + tud_int_handler(0); + } +#endif + if (irqs & (1 << TIMER0_INTERRUPT)) { + system_ticks++; + timer0_ev_pending_write(1); + } +} + +void board_init(void) +{ + irq_setmask(0); + irq_setie(1); + timer_init(); + return; +} + +void board_led_write(bool state) +{ + rgb_ctrl_write(0xff); + rgb_raw_write(state); +} + +uint32_t board_button_read(void) +{ + return 0; +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + int32_t offset = 0; + uint8_t const* buf8 = (uint8_t const*) buf; + for (offset = 0; offset < len; offset++) + { + if (!(messible_status_read() & CSR_MESSIBLE_STATUS_FULL_OFFSET)) + { + messible_in_write(buf8[offset]); + } + } + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif diff --git a/hw/bsp/fomu/family.cmake b/hw/bsp/fomu/family.cmake new file mode 100644 index 000000000..8d5ab144c --- /dev/null +++ b/hw/bsp/fomu/family.cmake @@ -0,0 +1,91 @@ +include_guard() + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR rv32i-ilp32 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS VALENTYUSB_EPTRI CACHE INTERNAL "") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/fomu.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/crt0-vexriscv.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/include + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for MSP432E4") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_VALENTYUSB_EPTRI ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/valentyusb/eptri/dcd_eptri.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) +endfunction() diff --git a/hw/bsp/fomu/family.mk b/hw/bsp/fomu/family.mk index f8a3c9ebf..d4b6eaea6 100644 --- a/hw/bsp/fomu/family.mk +++ b/hw/bsp/fomu/family.mk @@ -1,14 +1,15 @@ # Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack CROSS_COMPILE = riscv-none-embed- +CPU_CORE ?= rv32i-ilp32 + CFLAGS += \ -flto \ - -march=rv32i \ - -mabi=ilp32 \ - -nostdlib \ -DCFG_TUSB_MCU=OPT_MCU_VALENTYUSB_EPTRI -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostdlib \ + --specs=nosys.specs --specs=nano.specs \ # All source paths should be relative to the top level. LD_FILE = $(FAMILY_PATH)/fomu.ld diff --git a/hw/bsp/fomu/fomu.c b/hw/bsp/fomu/fomu.c deleted file mode 100644 index d155b743d..000000000 --- a/hw/bsp/fomu/fomu.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include -#include -#include "../board_api.h" -#include "csr.h" -#include "irq.h" - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void fomu_error(uint32_t line) -{ - (void)line; - TU_BREAKPOINT(); -} - -volatile uint32_t system_ticks = 0; -static void timer_init(void) -{ - int t; - - timer0_en_write(0); - t = CONFIG_CLOCK_FREQUENCY / 1000; // 1000 kHz tick - timer0_reload_write(t); - timer0_load_write(t); - timer0_en_write(1); - timer0_ev_enable_write(1); - timer0_ev_pending_write(1); - irq_setmask(irq_getmask() | (1 << TIMER0_INTERRUPT)); -} - -void isr(void) -{ - unsigned int irqs; - - irqs = irq_pending() & irq_getmask(); - -#if CFG_TUD_ENABLED - if (irqs & (1 << USB_INTERRUPT)) { - tud_int_handler(0); - } -#endif - if (irqs & (1 << TIMER0_INTERRUPT)) { - system_ticks++; - timer0_ev_pending_write(1); - } -} - -void board_init(void) -{ - irq_setmask(0); - irq_setie(1); - timer_init(); - return; -} - -void board_led_write(bool state) -{ - rgb_ctrl_write(0xff); - rgb_raw_write(state); -} - -uint32_t board_button_read(void) -{ - return 0; -} - -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; - (void) len; - return 0; -} - -int board_uart_write(void const * buf, int len) -{ - int32_t offset = 0; - uint8_t const* buf8 = (uint8_t const*) buf; - for (offset = 0; offset < len; offset++) - { - if (!(messible_status_read() & CSR_MESSIBLE_STATUS_FULL_OFFSET)) - { - messible_in_write(buf8[offset]); - } - } - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -uint32_t board_millis(void) -{ - return system_ticks; -} -#endif diff --git a/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.cmake b/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.cmake new file mode 100644 index 000000000..403ac08cf --- /dev/null +++ b/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.cmake @@ -0,0 +1,13 @@ +set(JLINK_DEVICE gd32vf103cbt6) + +set(SDK_BSP_DIR ${SOC_DIR}/Board/gd32vf103c_longan_nano) +set(LD_FILE_GNU ${SDK_BSP_DIR}/Source/GCC/gcc_gd32vf103xb_flashxip.ld) + +function(update_board TARGET) + target_sources(${TARGET} PUBLIC + ${SDK_BSP_DIR}/Source/gd32vf103c_longan_nano.c + ) + target_include_directories(${TARGET} PUBLIC + ${SDK_BSP_DIR}/Include + ) +endfunction() diff --git a/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.mk b/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.mk index 3b8944452..fc49b7317 100644 --- a/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.mk +++ b/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.mk @@ -10,4 +10,3 @@ INC += $(TOP)/$(LONGAN_NANO_SDK_BSP)/Include # Longan Nano 128k ROM 32k RAM JLINK_DEVICE = gd32vf103cbt6 -#JLINK_DEVICE = gd32vf103c8t6 # Longan Nano Lite 64k ROM 20k RAM diff --git a/hw/bsp/gd32vf103/family.c b/hw/bsp/gd32vf103/family.c index 27d7e87bb..d4a819fb3 100644 --- a/hw/bsp/gd32vf103/family.c +++ b/hw/bsp/gd32vf103/family.c @@ -24,11 +24,11 @@ * This file is part of the TinyUSB stack. */ -#include "board.h" #include "drv_usb_hw.h" #include "drv_usb_dev.h" -#include "../board_api.h" +#include "bsp/board_api.h" +#include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler diff --git a/hw/bsp/gd32vf103/family.cmake b/hw/bsp/gd32vf103/family.cmake new file mode 100644 index 000000000..5f4a3da8d --- /dev/null +++ b/hw/bsp/gd32vf103/family.cmake @@ -0,0 +1,119 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/gd/nuclei-sdk) +set(SOC_DIR ${SDK_DIR}/SoC/gd32vf103) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR rv32imac-ilp32 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS GD32VF103 CACHE INTERNAL "") + +set(JLINK_IF jtag) + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + if (NOT DEFINED LD_FILE_GNU) + message(FATAL_ERROR "LD_FILE_GNU is not defined") + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU + ${SOC_DIR}/Common/Source/GCC/startup_gd32vf103.S + ${SOC_DIR}/Common/Source/GCC/intexc_gd32vf103.S + ) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_gd32vf103.c + ${SOC_DIR}/Common/Source/Drivers/gd32vf103_rcu.c + ${SOC_DIR}/Common/Source/Drivers/gd32vf103_gpio.c + ${SOC_DIR}/Common/Source/Drivers/Usb/gd32vf103_usb_hw.c + ${SOC_DIR}/Common/Source/Drivers/gd32vf103_usart.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/NMSIS/Core/Include + ${SOC_DIR}/Common/Include + ${SOC_DIR}/Common/Include/Usb + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + DOWNLOAD_MODE=DOWNLOAD_MODE_FLASHXIP + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC + -mcmodel=medlow + -mstrict-align + ) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for MSP432E4") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ${SOC_DIR}/Common/Source/Stubs/sbrk.c + ${SOC_DIR}/Common/Source/Stubs/close.c + ${SOC_DIR}/Common/Source/Stubs/isatty.c + ${SOC_DIR}/Common/Source/Stubs/fstat.c + ${SOC_DIR}/Common/Source/Stubs/lseek.c + ${SOC_DIR}/Common/Source/Stubs/read.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_GD32VF103 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/gd32vf103/family.mk b/hw/bsp/gd32vf103/family.mk index 1725559c4..28e48a6b5 100644 --- a/hw/bsp/gd32vf103/family.mk +++ b/hw/bsp/gd32vf103/family.mk @@ -9,7 +9,6 @@ CROSS_COMPILE ?= riscv-none-embed- # Submodules NUCLEI_SDK = hw/mcu/gd/nuclei-sdk -DEPS_SUBMODULES += $(NUCLEI_SDK) # Nuclei-SDK paths GD32VF103_SDK_SOC = $(NUCLEI_SDK)/SoC/gd32vf103 @@ -18,12 +17,9 @@ LIBC_STUBS = $(GD32VF103_SDK_SOC)/Common/Source/Stubs STARTUP_ASM = $(GD32VF103_SDK_SOC)/Common/Source/GCC include $(TOP)/$(BOARD_PATH)/board.mk - -SKIP_NANOLIB = 1 +CPU_CORE ?= rv32imac-ilp32 CFLAGS += \ - -march=rv32imac \ - -mabi=ilp32 \ -mcmodel=medlow \ -mstrict-align \ -nostdlib -nostartfiles \ @@ -35,10 +31,10 @@ CFLAGS += -Wno-error=unused-parameter SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ - $(GD32VF103_SDK_DRIVER)/gd32vf103_rcu.c \ $(GD32VF103_SDK_DRIVER)/gd32vf103_gpio.c \ - $(GD32VF103_SDK_DRIVER)/Usb/gd32vf103_usb_hw.c \ + $(GD32VF103_SDK_DRIVER)/gd32vf103_rcu.c \ $(GD32VF103_SDK_DRIVER)/gd32vf103_usart.c \ + $(GD32VF103_SDK_DRIVER)/Usb/gd32vf103_usb_hw.c \ $(LIBC_STUBS)/sbrk.c \ $(LIBC_STUBS)/close.c \ $(LIBC_STUBS)/isatty.c \ diff --git a/hw/bsp/lpc51/family.cmake b/hw/bsp/lpc51/family.cmake index dd0ef6d1b..b9dd8829e 100644 --- a/hw/bsp/lpc51/family.cmake +++ b/hw/bsp/lpc51/family.cmake @@ -34,7 +34,6 @@ function(add_board_target BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} # driver - ${SDK_DIR}/drivers/common/fsl_common_arm.c ${SDK_DIR}/drivers/lpc_gpio/fsl_gpio.c ${SDK_DIR}/drivers/flexcomm/fsl_flexcomm.c ${SDK_DIR}/drivers/flexcomm/fsl_usart.c diff --git a/src/device/usbd.c b/src/device/usbd.c index e51aa0fc4..6aeaa699f 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -90,16 +90,16 @@ tu_static usbd_device_t _usbd_dev; // Class Driver //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL - #define DRIVER_NAME(_name) .name = _name, + #define DRIVER_NAME(_name) _name #else - #define DRIVER_NAME(_name) + #define DRIVER_NAME(_name) NULL #endif // Built-in class drivers tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_CDC { - DRIVER_NAME("CDC") + .name = DRIVER_NAME("CDC"), .init = cdcd_init, .deinit = cdcd_deinit, .reset = cdcd_reset, @@ -112,7 +112,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_MSC { - DRIVER_NAME("MSC") + .name = DRIVER_NAME("MSC"), .init = mscd_init, .deinit = NULL, .reset = mscd_reset, @@ -125,7 +125,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_HID { - DRIVER_NAME("HID") + .name = DRIVER_NAME("HID"), .init = hidd_init, .deinit = hidd_deinit, .reset = hidd_reset, @@ -138,7 +138,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_AUDIO { - DRIVER_NAME("AUDIO") + .name = DRIVER_NAME("AUDIO"), .init = audiod_init, .deinit = audiod_deinit, .reset = audiod_reset, @@ -151,7 +151,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_VIDEO { - DRIVER_NAME("VIDEO") + .name = DRIVER_NAME("VIDEO"), .init = videod_init, .deinit = videod_deinit, .reset = videod_reset, @@ -164,7 +164,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_MIDI { - DRIVER_NAME("MIDI") + .name = DRIVER_NAME("MIDI"), .init = midid_init, .deinit = midid_deinit, .open = midid_open, @@ -177,7 +177,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_VENDOR { - DRIVER_NAME("VENDOR") + .name = DRIVER_NAME("VENDOR"), .init = vendord_init, .deinit = vendord_deinit, .reset = vendord_reset, @@ -190,7 +190,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_USBTMC { - DRIVER_NAME("TMC") + .name = DRIVER_NAME("TMC"), .init = usbtmcd_init_cb, .deinit = usbtmcd_deinit, .reset = usbtmcd_reset_cb, @@ -203,7 +203,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_DFU_RUNTIME { - DRIVER_NAME("DFU-RUNTIME") + .name = DRIVER_NAME("DFU-RUNTIME"), .init = dfu_rtd_init, .deinit = dfu_rtd_deinit, .reset = dfu_rtd_reset, @@ -216,7 +216,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_DFU { - DRIVER_NAME("DFU") + .name = DRIVER_NAME("DFU"), .init = dfu_moded_init, .deinit = dfu_moded_deinit, .reset = dfu_moded_reset, @@ -229,7 +229,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM { - DRIVER_NAME("NET") + .name = DRIVER_NAME("NET"), .init = netd_init, .deinit = netd_deinit, .reset = netd_reset, @@ -242,7 +242,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_BTH { - DRIVER_NAME("BTH") + .name = DRIVER_NAME("BTH"), .init = btd_init, .deinit = btd_deinit, .reset = btd_reset, diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 47752f32c..7eb504246 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -23,8 +23,8 @@ * * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_USBD_PVT_H_ -#define _TUSB_USBD_PVT_H_ +#ifndef TUSB_USBD_PVT_H_ +#define TUSB_USBD_PVT_H_ #include "osal/osal.h" #include "common/tusb_fifo.h" @@ -40,10 +40,7 @@ //--------------------------------------------------------------------+ typedef struct { - #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL char const* name; - #endif - void (* init ) (void); bool (* deinit ) (void); void (* reset ) (uint8_t rhport); diff --git a/test/hil/hfp.json b/test/hil/hfp.json new file mode 100644 index 000000000..e79a3cfc9 --- /dev/null +++ b/test/hil/hfp.json @@ -0,0 +1,25 @@ +{ + "boards": [ + { + "name": "stm32l412nucleo", + "uid": "41003B000E504E5457323020", + "flasher": "jlink", + "flasher_sn": "774470029", + "flasher_args": "-device STM32L412KB" + }, + { + "name": "stm32f746disco", + "uid": "210041000C51343237303334", + "flasher": "jlink", + "flasher_sn": "770935966", + "flasher_args": "-device STM32F746NG" + }, + { + "name": "lpcxpresso43s67", + "uid": "08F000044528BAAA8D858F58C50700F5", + "flasher": "jlink", + "flasher_sn": "728973776", + "flasher_args": "-device LPC43S67_M4" + } + ] +} diff --git a/test/hil/hil_hfp.json b/test/hil/hil_hfp.json deleted file mode 100644 index e79a3cfc9..000000000 --- a/test/hil/hil_hfp.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "boards": [ - { - "name": "stm32l412nucleo", - "uid": "41003B000E504E5457323020", - "flasher": "jlink", - "flasher_sn": "774470029", - "flasher_args": "-device STM32L412KB" - }, - { - "name": "stm32f746disco", - "uid": "210041000C51343237303334", - "flasher": "jlink", - "flasher_sn": "770935966", - "flasher_args": "-device STM32F746NG" - }, - { - "name": "lpcxpresso43s67", - "uid": "08F000044528BAAA8D858F58C50700F5", - "flasher": "jlink", - "flasher_sn": "728973776", - "flasher_args": "-device LPC43S67_M4" - } - ] -} diff --git a/test/hil/hil_pi4.json b/test/hil/hil_pi4.json deleted file mode 100644 index 8aff81910..000000000 --- a/test/hil/hil_pi4.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "boards": [ - { - "name": "raspberry_pi_pico", - "uid": "E6614C311B764A37", - "flasher": "openocd", - "flasher_sn": "E6614103E72C1D2F", - "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"" - }, - { - "name": "espressif_s3_devkitm", - "uid": "84F703C084E4", - "tests": [ - "cdc_msc_freertos", "hid_composite_freertos" - ], - "flasher": "esptool", - "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", - "flasher_args": "-b 1500000" - }, - { - "name": "feather_nrf52840_express", - "uid": "1F0479CD0F764471", - "flasher": "jlink", - "flasher_sn": "000682804350", - "flasher_args": "-device nrf52840_xxaa" - }, - { - "name": "itsybitsy_m4", - "uid": "D784B28C5338533335202020FF044726", - "flasher": "bossac", - "flashser_vendor": "Adafruit Industries", - "flasher_product": "ItsyBitsy M4 Express", - "flasher_reset_pin": "2", - "flasher_args": "--offset 0x4000" - } - ] -} diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 7f03ce43f..dffb81765 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -33,12 +33,14 @@ import serial import subprocess import json import glob +import platform # for RPI double reset -try: - import gpiozero -except ImportError: - pass +if platform.machine() == 'aarch64': + try: + import gpiozero + except ImportError: + pass ENUM_TIMEOUT = 10 @@ -111,27 +113,39 @@ def read_disk_file(id, fname): # ------------------------------------------------------------- # Flashing firmware # ------------------------------------------------------------- +def run_cmd(cmd): + # print(cmd) + r = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + title = 'command error' + if r.returncode != 0: + # print build output if failed + if os.getenv('CI'): + print(f"::group::{title}") + print(r.stdout.decode("utf-8")) + print(f"::endgroup::") + else: + print(title) + print(r.stdout.decode("utf-8")) + return r + + def flash_jlink(board, firmware): - script = ['halt', 'r', f'loadfile {firmware}', 'r', 'go', 'exit'] + script = ['halt', 'r', f'loadfile {firmware}.elf', 'r', 'go', 'exit'] with open('flash.jlink', 'w') as f: f.writelines(f'{s}\n' for s in script) - ret = subprocess.run( - f'JLinkExe -USB {board["flasher_sn"]} {board["flasher_args"]} -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile flash.jlink', - shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + ret = run_cmd(f'JLinkExe -USB {board["flasher_sn"]} {board["flasher_args"]} -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile flash.jlink') os.remove('flash.jlink') return ret def flash_openocd(board, firmware): - ret = subprocess.run( - f'openocd -c "adapter serial {board["flasher_sn"]}" {board["flasher_args"]} -c "program {firmware} reset exit"', - shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + ret = run_cmd(f'openocd -c "adapter serial {board["flasher_sn"]}" {board["flasher_args"]} -c "program {firmware}.elf reset exit"') return ret def flash_esptool(board, firmware): port = get_serial_dev(board["flasher_sn"], None, None, 0) - dir = os.path.dirname(firmware) + dir = os.path.dirname(f'{firmware}.bin') with open(f'{dir}/config.env') as f: IDF_TARGET = json.load(f)['IDF_TARGET'] with open(f'{dir}/flash_args') as f: @@ -154,9 +168,11 @@ def doublereset_with_rpi_gpio(board): time.sleep(0.1) led.on() + def flash_bossac(board, firmware): # double reset to enter bootloader - doublereset_with_rpi_gpio(board) + if platform.machine() == 'aarch64': + doublereset_with_rpi_gpio(board) port = get_serial_dev(board["uid"], board["flashser_vendor"], board["flasher_product"], 0) timeout = ENUM_TIMEOUT @@ -169,8 +185,7 @@ def flash_bossac(board, firmware): assert timeout, 'bossac bootloader is not available' # sleep a bit more for bootloader to be ready time.sleep(0.5) - ret = subprocess.run(f'bossac --port {port} {board["flasher_args"]} -U -i -R -e -w {firmware}', shell=True, stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) + ret = run_cmd(f'bossac --port {port} {board["flasher_args"]} -U -i -R -e -w {firmware}.bin') return ret # ------------------------------------------------------------- @@ -325,7 +340,8 @@ def main(config_file, board): config_boards = [e for e in config['boards'] if e['name'] in board] for item in config_boards: - print(f'Testing board:{item["name"]}') + name = item['name'] + print(f'Testing board:{name}') flasher = item['flasher'].lower() # default to all tests @@ -344,29 +360,12 @@ def main(config_file, board): test_list.remove(skip) for test in test_list: - fw_list = [ - # cmake: esp32 & samd51 use .bin file - f'cmake-build/cmake-build-{item["name"]}/device/{test}/{test}.elf', - f'cmake-build/cmake-build-{item["name"]}/device/{test}/{test}.bin', - # make - f'examples/device/{test}/_build/{item["name"]}/{test}.elf' - ] - - fw = None - for f in fw_list: - if os.path.isfile(f): - fw = f - break - - if fw is None: - print(f'Cannot find binary file for {test}') - sys.exit(-1) - + fw_name = f'cmake-build/cmake-build-{name}/device/{test}/{test}' print(f' {test} ...', end='') # flash firmware. It may fail randomly, retry a few times for i in range(3): - ret = globals()[f'flash_{flasher}'](item, fw) + ret = globals()[f'flash_{flasher}'](item, fw_name) if ret.returncode == 0: break else: diff --git a/test/hil/pi4.json b/test/hil/pi4.json new file mode 100644 index 000000000..04329bb64 --- /dev/null +++ b/test/hil/pi4.json @@ -0,0 +1,27 @@ +{ + "boards": [ + { + "name": "raspberry_pi_pico", + "uid": "E6614C311B764A37", + "flasher": "openocd", + "flasher_sn": "E6614103E72C1D2F", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"" + }, + { + "name": "feather_nrf52840_express", + "uid": "1F0479CD0F764471", + "flasher": "jlink", + "flasher_sn": "000682804350", + "flasher_args": "-device nrf52840_xxaa" + }, + { + "name": "itsybitsy_m4", + "uid": "D784B28C5338533335202020FF044726", + "flasher": "bossac", + "flashser_vendor": "Adafruit Industries", + "flasher_product": "ItsyBitsy M4 Express", + "flasher_reset_pin": "2", + "flasher_args": "--offset 0x4000" + } + ] +} diff --git a/test/hil/pi4_esp32.json b/test/hil/pi4_esp32.json new file mode 100644 index 000000000..c95dd2d4e --- /dev/null +++ b/test/hil/pi4_esp32.json @@ -0,0 +1,14 @@ +{ + "boards": [ + { + "name": "espressif_s3_devkitm", + "uid": "84F703C084E4", + "tests": [ + "cdc_msc_freertos", "hid_composite_freertos" + ], + "flasher": "esptool", + "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", + "flasher_args": "-b 1500000" + } + ] +} diff --git a/tools/build.py b/tools/build.py new file mode 100644 index 000000000..884cd56f4 --- /dev/null +++ b/tools/build.py @@ -0,0 +1,177 @@ +import os +import sys +import time +import subprocess +import click +from pathlib import Path +from multiprocessing import Pool + +import build_utils + +SUCCEEDED = "\033[32msucceeded\033[0m" +FAILED = "\033[31mfailed\033[0m" + +build_separator = '-' * 106 + + +def run_cmd(cmd): + #print(cmd) + r = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + title = 'command error' + if r.returncode != 0: + # print build output if failed + if os.getenv('CI'): + print(f"::group::{title}") + print(r.stdout.decode("utf-8")) + print(f"::endgroup::") + else: + print(title) + print(r.stdout.decode("utf-8")) + return r + +def find_family(board): + bsp_dir = Path("hw/bsp") + for family_dir in bsp_dir.iterdir(): + if family_dir.is_dir(): + board_dir = family_dir / 'boards' / board + if board_dir.exists(): + return family_dir.name + return None + + +def get_examples(family): + all_examples = [] + for d in os.scandir("examples"): + if d.is_dir() and 'cmake' not in d.name and 'build_system' not in d.name: + for entry in os.scandir(d.path): + if entry.is_dir() and 'cmake' not in entry.name: + if family != 'espressif' or 'freertos' in entry.name: + all_examples.append(d.name + '/' + entry.name) + + if family == 'espressif': + all_examples.append('device/board_test') + all_examples.append('device/video_capture') + all_examples.sort() + return all_examples + + +def build_board_cmake(board, toolchain): + start_time = time.monotonic() + ret = [0, 0, 0] + + build_dir = f"cmake-build/cmake-build-{board}" + family = find_family(board) + if family == 'espressif': + # for espressif, we have to build example individually + all_examples = get_examples(family) + for example in all_examples: + r = run_cmd(f'cmake examples/{example} -B {build_dir}/{example} -G "Ninja" -DBOARD={board} -DMAX3421_HOST=1') + if r.returncode == 0: + r = run_cmd(f'cmake --build {build_dir}/{example}') + if r.returncode == 0: + ret[0] += 1 + else: + ret[1] += 1 + else: + r = run_cmd(f'cmake examples -B {build_dir} -G "Ninja" -DBOARD={board} -DCMAKE_BUILD_TYPE=MinSizeRel -DTOOLCHAIN={toolchain}') + if r.returncode == 0: + r = run_cmd(f"cmake --build {build_dir}") + if r.returncode == 0: + ret[0] += 1 + else: + ret[1] += 1 + + duration = time.monotonic() - start_time + + if ret[1] == 0: + status = SUCCEEDED + else: + status = FAILED + + flash_size = "-" + sram_size = "-" + example = 'all' + title = build_utils.build_format.format(example, board, status, "{:.2f}s".format(duration), flash_size, sram_size) + print(title) + return ret + + +def build_family(family, toolchain, build_system): + all_boards = [] + for entry in os.scandir(f"hw/bsp/{family}/boards"): + if entry.is_dir() and entry.name != 'pico_sdk': + all_boards.append(entry.name) + all_boards.sort() + + # success, failed, skipped + ret = [0, 0, 0] + if build_system == 'cmake': + for board in all_boards: + if build_board_cmake(board, toolchain): + ret[0] += 1 + else: + ret[1] += 1 + elif build_system == 'make': + all_examples = get_examples(family) + for example in all_examples: + with Pool(processes=os.cpu_count()) as pool: + pool_args = list((map(lambda b, e=example, o=f"TOOLCHAIN={toolchain}": [e, b, o], all_boards))) + r = pool.starmap(build_utils.build_example, pool_args) + # sum all element of same index (column sum) + rsum = list(map(sum, list(zip(*r)))) + ret[0] += rsum[0] + ret[1] += rsum[1] + ret[2] += rsum[2] + return ret + + +@click.command() +@click.argument('families', nargs=-1, required=False) +@click.option('-b', '--board', multiple=True, default=None, help='Boards to build') +@click.option('-t', '--toolchain', default='gcc', help='Toolchain to use, default is gcc') +@click.option('-s', '--build-system', default='cmake', help='Build system to use, default is cmake') +def main(families, board, toolchain, build_system): + if len(families) == 0 and len(board) == 0: + print("Please specify families or board to build") + return 1 + + print(build_separator) + print(build_utils.build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) + total_time = time.monotonic() + total_result = [0, 0, 0] + + # build families: cmake, make + if families is not None: + all_families = [] + if 'all' in families: + for entry in os.scandir("hw/bsp"): + if entry.is_dir() and entry.name != 'espressif' and os.path.isfile(entry.path + "/family.cmake"): + all_families.append(entry.name) + else: + all_families = list(families) + all_families.sort() + + # succeeded, failed + for f in all_families: + fret = build_family(f, toolchain, build_system) + total_result[0] += fret[0] + total_result[1] += fret[1] + total_result[2] += fret[2] + + # build board (only cmake) + if board is not None: + for b in board: + r = build_board_cmake(b, toolchain) + total_result[0] += r[0] + total_result[1] += r[1] + total_result[2] += r[2] + + total_time = time.monotonic() - total_time + print(build_separator) + print(f"Build Summary: {total_result[0]} {SUCCEEDED}, {total_result[1]} {FAILED} and took {total_time:.2f}s") + print(build_separator) + return total_result[1] + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/tools/build_board.py b/tools/build_board.py deleted file mode 100644 index 13376d126..000000000 --- a/tools/build_board.py +++ /dev/null @@ -1,69 +0,0 @@ -import os -import sys -import time -import subprocess -from multiprocessing import Pool - -import build_utils - -SUCCEEDED = "\033[32msucceeded\033[0m" -FAILED = "\033[31mfailed\033[0m" -SKIPPED = "\033[33mskipped\033[0m" - -build_separator = '-' * 106 - - -def filter_with_input(mylist): - if len(sys.argv) > 1: - input_args = list(set(mylist).intersection(sys.argv)) - if len(input_args) > 0: - mylist[:] = input_args - - -if __name__ == '__main__': - # If examples are not specified in arguments, build all - all_examples = [] - for dir1 in os.scandir("examples"): - if dir1.is_dir(): - for entry in os.scandir(dir1.path): - if entry.is_dir(): - all_examples.append(dir1.name + '/' + entry.name) - filter_with_input(all_examples) - all_examples.sort() - - # If boards are not specified in arguments, build all - all_boards = [] - for entry in os.scandir("hw/bsp"): - if entry.is_dir() and os.path.exists(entry.path + "/board.mk"): - all_boards.append(entry.name) - filter_with_input(all_boards) - all_boards.sort() - - # Get dependencies - for b in all_boards: - subprocess.run("make -C examples/device/board_test BOARD={} get-deps".format(b), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - print(build_separator) - print(build_utils.build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) - total_time = time.monotonic() - - # succeeded, failed, skipped - total_result = [0, 0, 0] - for example in all_examples: - print(build_separator) - with Pool(processes=os.cpu_count()) as pool: - pool_args = list((map(lambda b, e=example, o='': [e, b, o], all_boards))) - result = pool.starmap(build_utils.build_example, pool_args) - # sum all element of same index (column sum) - result = list(map(sum, list(zip(*result)))) - - # add to total result - total_result = list(map(lambda x, y: x + y, total_result, result)) - - total_time = time.monotonic() - total_time - print(build_separator) - print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(total_result[0], SUCCEEDED, total_result[1], - FAILED, total_result[2], SKIPPED, total_time)) - print(build_separator) - - sys.exit(total_result[1]) diff --git a/tools/build_cmake.py b/tools/build_cmake.py deleted file mode 100644 index 2eda3f90f..000000000 --- a/tools/build_cmake.py +++ /dev/null @@ -1,105 +0,0 @@ -import os -import sys -import time -import subprocess -import pathlib -from multiprocessing import Pool - -import build_utils - -SUCCEEDED = "\033[32msucceeded\033[0m" -FAILED = "\033[31mfailed\033[0m" -SKIPPED = "\033[33mskipped\033[0m" - -build_separator = '-' * 106 - -def filter_with_input(mylist): - if len(sys.argv) > 1: - input_args = list(set(mylist).intersection(sys.argv)) - if len(input_args) > 0: - mylist[:] = input_args - - -def build_family(family, cmake_option): - all_boards = [] - for entry in os.scandir("hw/bsp/{}/boards".format(family)): - if entry.is_dir() and entry.name != 'pico_sdk': - all_boards.append(entry.name) - all_boards.sort() - - # success, failed, skipped - ret = [0, 0, 0] - for board in all_boards: - start_time = time.monotonic() - - build_dir = f"cmake-build/cmake-build-{board}" - - # Generate build - r = subprocess.run(f"cmake examples -B {build_dir} -G \"Ninja\" -DFAMILY={family} -DBOARD" - f"={board} -DCMAKE_BUILD_TYPE=MinSizeRel {cmake_option}", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - # Build - if r.returncode == 0: - r = subprocess.run(f"cmake --build {build_dir}", shell=True, stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - - duration = time.monotonic() - start_time - - if r.returncode == 0: - status = SUCCEEDED - ret[0] += 1 - else: - status = FAILED - ret[1] += 1 - - flash_size = "-" - sram_size = "-" - example = 'all' - title = build_utils.build_format.format(example, board, status, "{:.2f}s".format(duration), flash_size, sram_size) - - if os.getenv('CI'): - # always print build output if in CI - print(f"::group::{title}") - print(r.stdout.decode("utf-8")) - print(f"::endgroup::") - else: - # print build output if failed - print(title) - if r.returncode != 0: - print(r.stdout.decode("utf-8")) - - return ret - - -if __name__ == '__main__': - cmake_options = '' - for a in sys.argv[1:]: - if a.startswith('-'): - cmake_options += ' ' + a - - # If family are not specified in arguments, build all supported - all_families = [] - for entry in os.scandir("hw/bsp"): - if entry.is_dir() and entry.name != 'espressif' and os.path.isfile(entry.path + "/family.cmake"): - all_families.append(entry.name) - filter_with_input(all_families) - all_families.sort() - - print(build_separator) - print(build_utils.build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) - total_time = time.monotonic() - - # succeeded, failed, skipped - total_result = [0, 0, 0] - for family in all_families: - fret = build_family(family, cmake_options) - if len(fret) == len(total_result): - total_result = [total_result[i] + fret[i] for i in range(len(fret))] - - total_time = time.monotonic() - total_time - print(build_separator) - print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(total_result[0], SUCCEEDED, total_result[1], - FAILED, total_result[2], SKIPPED, total_time)) - print(build_separator) - - sys.exit(total_result[1]) diff --git a/tools/build_make.py b/tools/build_make.py deleted file mode 100644 index 240fc8d64..000000000 --- a/tools/build_make.py +++ /dev/null @@ -1,80 +0,0 @@ -import os -import sys -import time -from multiprocessing import Pool - -import build_utils - -SUCCEEDED = "\033[32msucceeded\033[0m" -FAILED = "\033[31mfailed\033[0m" -SKIPPED = "\033[33mskipped\033[0m" - -build_separator = '-' * 106 - - -def filter_with_input(mylist): - if len(sys.argv) > 1: - input_args = list(set(mylist).intersection(sys.argv)) - if len(input_args) > 0: - mylist[:] = input_args - - -def build_family(example, family, make_option): - all_boards = [] - for entry in os.scandir("hw/bsp/{}/boards".format(family)): - if entry.is_dir() and entry.name != 'pico_sdk': - all_boards.append(entry.name) - filter_with_input(all_boards) - all_boards.sort() - - with Pool(processes=os.cpu_count()) as pool: - pool_args = list((map(lambda b, e=example, o=make_option: [e, b, o], all_boards))) - result = pool.starmap(build_utils.build_example, pool_args) - # sum all element of same index (column sum) - return list(map(sum, list(zip(*result)))) - - -if __name__ == '__main__': - make_option = '' - for a in sys.argv: - if 'TOOLCHAIN=' in sys.argv: - make_option += ' ' + a - - # If examples are not specified in arguments, build all - all_examples = [] - for d in os.scandir("examples"): - if d.is_dir() and 'cmake' not in d.name and 'build_system' not in d.name: - for entry in os.scandir(d.path): - if entry.is_dir() and 'cmake' not in entry.name: - all_examples.append(d.name + '/' + entry.name) - filter_with_input(all_examples) - all_examples.sort() - - # If family are not specified in arguments, build all - all_families = [] - for entry in os.scandir("hw/bsp"): - if entry.is_dir() and os.path.isdir(entry.path + "/boards") and entry.name != 'espressif': - all_families.append(entry.name) - filter_with_input(all_families) - all_families.sort() - - print(build_separator) - print(build_utils.build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) - total_time = time.monotonic() - - # succeeded, failed, skipped - total_result = [0, 0, 0] - for example in all_examples: - print(build_separator) - for family in all_families: - fret = build_family(example, family, make_option) - if len(fret) == len(total_result): - total_result = [total_result[i] + fret[i] for i in range(len(fret))] - - total_time = time.monotonic() - total_time - print(build_separator) - print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(total_result[0], SUCCEEDED, total_result[1], - FAILED, total_result[2], SKIPPED, total_time)) - print(build_separator) - - sys.exit(total_result[1]) diff --git a/tools/get_deps.py b/tools/get_deps.py index cdb5dafe1..bca38fc80 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -1,3 +1,4 @@ +import click import sys import subprocess from pathlib import Path @@ -227,27 +228,46 @@ def get_a_dep(d): return 0 -# Arguments can be -# - family name -# - specific deps path -# - all -if __name__ == "__main__": +def find_family(board): + bsp_dir = Path(TOP / "hw/bsp") + for family_dir in bsp_dir.iterdir(): + if family_dir.is_dir(): + board_dir = family_dir / 'boards' / board + if board_dir.exists(): + return family_dir.name + return None + + +@click.command() +@click.argument('family', nargs=-1, required=False) +@click.option('-b', '--board', multiple=True, default=None, help='Boards to fetch') +def main(family, board): + if len(family) == 0 and len(board) == 0: + print("Please specify family or board to fetch") + return + status = 0 deps = list(deps_mandatory.keys()) - # get all if 'all' is argument - if len(sys.argv) == 2 and sys.argv[1] == 'all': + + if 'all' in family: deps += deps_optional.keys() else: - for arg in sys.argv[1:]: - if arg in deps_all.keys(): - # if arg is a dep, add it - deps.append(arg) - else: - # arg is a family name, add all deps of that family - for d in deps_optional: - if arg in deps_optional[d][2]: - deps.append(d) + family = list(family) + if board is not None: + for b in board: + f = find_family(b) + if f is not None: + family.append(f) + + for f in family: + for d in deps_optional: + if f in deps_optional[d][2]: + deps.append(d) with Pool() as pool: status = sum(pool.map(get_a_dep, deps)) - sys.exit(status) + return status + + +if __name__ == "__main__": + sys.exit(main()) -- cgit v1.3.1 From 2b9e53772e73c2bfd07bbbf4d6d2f0b33bcd22fb Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 16:28:25 +0200 Subject: Take updated change from cdc_device. --- src/class/vendor/vendor_device.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index e87ce3997..56ef098c7 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -36,6 +36,8 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + typedef struct { uint8_t itf_num; @@ -273,7 +275,6 @@ uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, ui bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - (void) rhport; (void) result; uint8_t itf = 0; @@ -300,7 +301,18 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint { if (tud_vendor_tx_cb) tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); // Send complete, try to send more if possible - tud_vendor_n_write_flush(itf); + if ( 0 == tud_vendor_n_write_flush(itf) ) + { + // If there is no data left, a ZLP should be sent if + // xferred_bytes is multiple of EP Packet size and not zero + if ( !tu_fifo_count(&p_itf->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE-1))) ) + { + if ( usbd_edpt_claim(rhport, p_itf->ep_in) ) + { + usbd_edpt_xfer(rhport, p_itf->ep_in, NULL, 0); + } + } + } } return true; -- cgit v1.3.1 From 015b57b6ef5cd24db8665c62e8fe209bce3e2b7e Mon Sep 17 00:00:00 2001 From: John Toniutti Date: Thu, 9 May 2024 17:05:14 +0200 Subject: Add missing key codes Source: https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf from page 57 to page 59 --- src/class/hid/hid.h | 389 +++++++++++++++++++++++++++++----------------------- 1 file changed, 218 insertions(+), 171 deletions(-) diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index e949f1f83..03ef24f78 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -366,177 +366,224 @@ typedef enum //--------------------------------------------------------------------+ // HID KEYCODE //--------------------------------------------------------------------+ -#define HID_KEY_NONE 0x00 -#define HID_KEY_A 0x04 -#define HID_KEY_B 0x05 -#define HID_KEY_C 0x06 -#define HID_KEY_D 0x07 -#define HID_KEY_E 0x08 -#define HID_KEY_F 0x09 -#define HID_KEY_G 0x0A -#define HID_KEY_H 0x0B -#define HID_KEY_I 0x0C -#define HID_KEY_J 0x0D -#define HID_KEY_K 0x0E -#define HID_KEY_L 0x0F -#define HID_KEY_M 0x10 -#define HID_KEY_N 0x11 -#define HID_KEY_O 0x12 -#define HID_KEY_P 0x13 -#define HID_KEY_Q 0x14 -#define HID_KEY_R 0x15 -#define HID_KEY_S 0x16 -#define HID_KEY_T 0x17 -#define HID_KEY_U 0x18 -#define HID_KEY_V 0x19 -#define HID_KEY_W 0x1A -#define HID_KEY_X 0x1B -#define HID_KEY_Y 0x1C -#define HID_KEY_Z 0x1D -#define HID_KEY_1 0x1E -#define HID_KEY_2 0x1F -#define HID_KEY_3 0x20 -#define HID_KEY_4 0x21 -#define HID_KEY_5 0x22 -#define HID_KEY_6 0x23 -#define HID_KEY_7 0x24 -#define HID_KEY_8 0x25 -#define HID_KEY_9 0x26 -#define HID_KEY_0 0x27 -#define HID_KEY_ENTER 0x28 -#define HID_KEY_ESCAPE 0x29 -#define HID_KEY_BACKSPACE 0x2A -#define HID_KEY_TAB 0x2B -#define HID_KEY_SPACE 0x2C -#define HID_KEY_MINUS 0x2D -#define HID_KEY_EQUAL 0x2E -#define HID_KEY_BRACKET_LEFT 0x2F -#define HID_KEY_BRACKET_RIGHT 0x30 -#define HID_KEY_BACKSLASH 0x31 -#define HID_KEY_EUROPE_1 0x32 -#define HID_KEY_SEMICOLON 0x33 -#define HID_KEY_APOSTROPHE 0x34 -#define HID_KEY_GRAVE 0x35 -#define HID_KEY_COMMA 0x36 -#define HID_KEY_PERIOD 0x37 -#define HID_KEY_SLASH 0x38 -#define HID_KEY_CAPS_LOCK 0x39 -#define HID_KEY_F1 0x3A -#define HID_KEY_F2 0x3B -#define HID_KEY_F3 0x3C -#define HID_KEY_F4 0x3D -#define HID_KEY_F5 0x3E -#define HID_KEY_F6 0x3F -#define HID_KEY_F7 0x40 -#define HID_KEY_F8 0x41 -#define HID_KEY_F9 0x42 -#define HID_KEY_F10 0x43 -#define HID_KEY_F11 0x44 -#define HID_KEY_F12 0x45 -#define HID_KEY_PRINT_SCREEN 0x46 -#define HID_KEY_SCROLL_LOCK 0x47 -#define HID_KEY_PAUSE 0x48 -#define HID_KEY_INSERT 0x49 -#define HID_KEY_HOME 0x4A -#define HID_KEY_PAGE_UP 0x4B -#define HID_KEY_DELETE 0x4C -#define HID_KEY_END 0x4D -#define HID_KEY_PAGE_DOWN 0x4E -#define HID_KEY_ARROW_RIGHT 0x4F -#define HID_KEY_ARROW_LEFT 0x50 -#define HID_KEY_ARROW_DOWN 0x51 -#define HID_KEY_ARROW_UP 0x52 -#define HID_KEY_NUM_LOCK 0x53 -#define HID_KEY_KEYPAD_DIVIDE 0x54 -#define HID_KEY_KEYPAD_MULTIPLY 0x55 -#define HID_KEY_KEYPAD_SUBTRACT 0x56 -#define HID_KEY_KEYPAD_ADD 0x57 -#define HID_KEY_KEYPAD_ENTER 0x58 -#define HID_KEY_KEYPAD_1 0x59 -#define HID_KEY_KEYPAD_2 0x5A -#define HID_KEY_KEYPAD_3 0x5B -#define HID_KEY_KEYPAD_4 0x5C -#define HID_KEY_KEYPAD_5 0x5D -#define HID_KEY_KEYPAD_6 0x5E -#define HID_KEY_KEYPAD_7 0x5F -#define HID_KEY_KEYPAD_8 0x60 -#define HID_KEY_KEYPAD_9 0x61 -#define HID_KEY_KEYPAD_0 0x62 -#define HID_KEY_KEYPAD_DECIMAL 0x63 -#define HID_KEY_EUROPE_2 0x64 -#define HID_KEY_APPLICATION 0x65 -#define HID_KEY_POWER 0x66 -#define HID_KEY_KEYPAD_EQUAL 0x67 -#define HID_KEY_F13 0x68 -#define HID_KEY_F14 0x69 -#define HID_KEY_F15 0x6A -#define HID_KEY_F16 0x6B -#define HID_KEY_F17 0x6C -#define HID_KEY_F18 0x6D -#define HID_KEY_F19 0x6E -#define HID_KEY_F20 0x6F -#define HID_KEY_F21 0x70 -#define HID_KEY_F22 0x71 -#define HID_KEY_F23 0x72 -#define HID_KEY_F24 0x73 -#define HID_KEY_EXECUTE 0x74 -#define HID_KEY_HELP 0x75 -#define HID_KEY_MENU 0x76 -#define HID_KEY_SELECT 0x77 -#define HID_KEY_STOP 0x78 -#define HID_KEY_AGAIN 0x79 -#define HID_KEY_UNDO 0x7A -#define HID_KEY_CUT 0x7B -#define HID_KEY_COPY 0x7C -#define HID_KEY_PASTE 0x7D -#define HID_KEY_FIND 0x7E -#define HID_KEY_MUTE 0x7F -#define HID_KEY_VOLUME_UP 0x80 -#define HID_KEY_VOLUME_DOWN 0x81 -#define HID_KEY_LOCKING_CAPS_LOCK 0x82 -#define HID_KEY_LOCKING_NUM_LOCK 0x83 -#define HID_KEY_LOCKING_SCROLL_LOCK 0x84 -#define HID_KEY_KEYPAD_COMMA 0x85 -#define HID_KEY_KEYPAD_EQUAL_SIGN 0x86 -#define HID_KEY_KANJI1 0x87 -#define HID_KEY_KANJI2 0x88 -#define HID_KEY_KANJI3 0x89 -#define HID_KEY_KANJI4 0x8A -#define HID_KEY_KANJI5 0x8B -#define HID_KEY_KANJI6 0x8C -#define HID_KEY_KANJI7 0x8D -#define HID_KEY_KANJI8 0x8E -#define HID_KEY_KANJI9 0x8F -#define HID_KEY_LANG1 0x90 -#define HID_KEY_LANG2 0x91 -#define HID_KEY_LANG3 0x92 -#define HID_KEY_LANG4 0x93 -#define HID_KEY_LANG5 0x94 -#define HID_KEY_LANG6 0x95 -#define HID_KEY_LANG7 0x96 -#define HID_KEY_LANG8 0x97 -#define HID_KEY_LANG9 0x98 -#define HID_KEY_ALTERNATE_ERASE 0x99 -#define HID_KEY_SYSREQ_ATTENTION 0x9A -#define HID_KEY_CANCEL 0x9B -#define HID_KEY_CLEAR 0x9C -#define HID_KEY_PRIOR 0x9D -#define HID_KEY_RETURN 0x9E -#define HID_KEY_SEPARATOR 0x9F -#define HID_KEY_OUT 0xA0 -#define HID_KEY_OPER 0xA1 -#define HID_KEY_CLEAR_AGAIN 0xA2 -#define HID_KEY_CRSEL_PROPS 0xA3 -#define HID_KEY_EXSEL 0xA4 -// RESERVED 0xA5-DF -#define HID_KEY_CONTROL_LEFT 0xE0 -#define HID_KEY_SHIFT_LEFT 0xE1 -#define HID_KEY_ALT_LEFT 0xE2 -#define HID_KEY_GUI_LEFT 0xE3 -#define HID_KEY_CONTROL_RIGHT 0xE4 -#define HID_KEY_SHIFT_RIGHT 0xE5 -#define HID_KEY_ALT_RIGHT 0xE6 -#define HID_KEY_GUI_RIGHT 0xE7 +#define HID_KEY_NONE 0x00 +#define HID_KEY_A 0x04 +#define HID_KEY_B 0x05 +#define HID_KEY_C 0x06 +#define HID_KEY_D 0x07 +#define HID_KEY_E 0x08 +#define HID_KEY_F 0x09 +#define HID_KEY_G 0x0A +#define HID_KEY_H 0x0B +#define HID_KEY_I 0x0C +#define HID_KEY_J 0x0D +#define HID_KEY_K 0x0E +#define HID_KEY_L 0x0F +#define HID_KEY_M 0x10 +#define HID_KEY_N 0x11 +#define HID_KEY_O 0x12 +#define HID_KEY_P 0x13 +#define HID_KEY_Q 0x14 +#define HID_KEY_R 0x15 +#define HID_KEY_S 0x16 +#define HID_KEY_T 0x17 +#define HID_KEY_U 0x18 +#define HID_KEY_V 0x19 +#define HID_KEY_W 0x1A +#define HID_KEY_X 0x1B +#define HID_KEY_Y 0x1C +#define HID_KEY_Z 0x1D +#define HID_KEY_1 0x1E +#define HID_KEY_2 0x1F +#define HID_KEY_3 0x20 +#define HID_KEY_4 0x21 +#define HID_KEY_5 0x22 +#define HID_KEY_6 0x23 +#define HID_KEY_7 0x24 +#define HID_KEY_8 0x25 +#define HID_KEY_9 0x26 +#define HID_KEY_0 0x27 +#define HID_KEY_ENTER 0x28 +#define HID_KEY_ESCAPE 0x29 +#define HID_KEY_BACKSPACE 0x2A +#define HID_KEY_TAB 0x2B +#define HID_KEY_SPACE 0x2C +#define HID_KEY_MINUS 0x2D +#define HID_KEY_EQUAL 0x2E +#define HID_KEY_BRACKET_LEFT 0x2F +#define HID_KEY_BRACKET_RIGHT 0x30 +#define HID_KEY_BACKSLASH 0x31 +#define HID_KEY_EUROPE_1 0x32 +#define HID_KEY_SEMICOLON 0x33 +#define HID_KEY_APOSTROPHE 0x34 +#define HID_KEY_GRAVE 0x35 +#define HID_KEY_COMMA 0x36 +#define HID_KEY_PERIOD 0x37 +#define HID_KEY_SLASH 0x38 +#define HID_KEY_CAPS_LOCK 0x39 +#define HID_KEY_F1 0x3A +#define HID_KEY_F2 0x3B +#define HID_KEY_F3 0x3C +#define HID_KEY_F4 0x3D +#define HID_KEY_F5 0x3E +#define HID_KEY_F6 0x3F +#define HID_KEY_F7 0x40 +#define HID_KEY_F8 0x41 +#define HID_KEY_F9 0x42 +#define HID_KEY_F10 0x43 +#define HID_KEY_F11 0x44 +#define HID_KEY_F12 0x45 +#define HID_KEY_PRINT_SCREEN 0x46 +#define HID_KEY_SCROLL_LOCK 0x47 +#define HID_KEY_PAUSE 0x48 +#define HID_KEY_INSERT 0x49 +#define HID_KEY_HOME 0x4A +#define HID_KEY_PAGE_UP 0x4B +#define HID_KEY_DELETE 0x4C +#define HID_KEY_END 0x4D +#define HID_KEY_PAGE_DOWN 0x4E +#define HID_KEY_ARROW_RIGHT 0x4F +#define HID_KEY_ARROW_LEFT 0x50 +#define HID_KEY_ARROW_DOWN 0x51 +#define HID_KEY_ARROW_UP 0x52 +#define HID_KEY_NUM_LOCK 0x53 +#define HID_KEY_KEYPAD_DIVIDE 0x54 +#define HID_KEY_KEYPAD_MULTIPLY 0x55 +#define HID_KEY_KEYPAD_SUBTRACT 0x56 +#define HID_KEY_KEYPAD_ADD 0x57 +#define HID_KEY_KEYPAD_ENTER 0x58 +#define HID_KEY_KEYPAD_1 0x59 +#define HID_KEY_KEYPAD_2 0x5A +#define HID_KEY_KEYPAD_3 0x5B +#define HID_KEY_KEYPAD_4 0x5C +#define HID_KEY_KEYPAD_5 0x5D +#define HID_KEY_KEYPAD_6 0x5E +#define HID_KEY_KEYPAD_7 0x5F +#define HID_KEY_KEYPAD_8 0x60 +#define HID_KEY_KEYPAD_9 0x61 +#define HID_KEY_KEYPAD_0 0x62 +#define HID_KEY_KEYPAD_DECIMAL 0x63 +#define HID_KEY_EUROPE_2 0x64 +#define HID_KEY_APPLICATION 0x65 +#define HID_KEY_POWER 0x66 +#define HID_KEY_KEYPAD_EQUAL 0x67 +#define HID_KEY_F13 0x68 +#define HID_KEY_F14 0x69 +#define HID_KEY_F15 0x6A +#define HID_KEY_F16 0x6B +#define HID_KEY_F17 0x6C +#define HID_KEY_F18 0x6D +#define HID_KEY_F19 0x6E +#define HID_KEY_F20 0x6F +#define HID_KEY_F21 0x70 +#define HID_KEY_F22 0x71 +#define HID_KEY_F23 0x72 +#define HID_KEY_F24 0x73 +#define HID_KEY_EXECUTE 0x74 +#define HID_KEY_HELP 0x75 +#define HID_KEY_MENU 0x76 +#define HID_KEY_SELECT 0x77 +#define HID_KEY_STOP 0x78 +#define HID_KEY_AGAIN 0x79 +#define HID_KEY_UNDO 0x7A +#define HID_KEY_CUT 0x7B +#define HID_KEY_COPY 0x7C +#define HID_KEY_PASTE 0x7D +#define HID_KEY_FIND 0x7E +#define HID_KEY_MUTE 0x7F +#define HID_KEY_VOLUME_UP 0x80 +#define HID_KEY_VOLUME_DOWN 0x81 +#define HID_KEY_LOCKING_CAPS_LOCK 0x82 +#define HID_KEY_LOCKING_NUM_LOCK 0x83 +#define HID_KEY_LOCKING_SCROLL_LOCK 0x84 +#define HID_KEY_KEYPAD_COMMA 0x85 +#define HID_KEY_KEYPAD_EQUAL_SIGN 0x86 +#define HID_KEY_KANJI1 0x87 +#define HID_KEY_KANJI2 0x88 +#define HID_KEY_KANJI3 0x89 +#define HID_KEY_KANJI4 0x8A +#define HID_KEY_KANJI5 0x8B +#define HID_KEY_KANJI6 0x8C +#define HID_KEY_KANJI7 0x8D +#define HID_KEY_KANJI8 0x8E +#define HID_KEY_KANJI9 0x8F +#define HID_KEY_LANG1 0x90 +#define HID_KEY_LANG2 0x91 +#define HID_KEY_LANG3 0x92 +#define HID_KEY_LANG4 0x93 +#define HID_KEY_LANG5 0x94 +#define HID_KEY_LANG6 0x95 +#define HID_KEY_LANG7 0x96 +#define HID_KEY_LANG8 0x97 +#define HID_KEY_LANG9 0x98 +#define HID_KEY_ALTERNATE_ERASE 0x99 +#define HID_KEY_SYSREQ_ATTENTION 0x9A +#define HID_KEY_CANCEL 0x9B +#define HID_KEY_CLEAR 0x9C +#define HID_KEY_PRIOR 0x9D +#define HID_KEY_RETURN 0x9E +#define HID_KEY_SEPARATOR 0x9F +#define HID_KEY_OUT 0xA0 +#define HID_KEY_OPER 0xA1 +#define HID_KEY_CLEAR_AGAIN 0xA2 +#define HID_KEY_CRSEL_PROPS 0xA3 +#define HID_KEY_EXSEL 0xA4 +// RESERVED 0xA5-AF +#define HID_KEY_KEYPAD_00 0xB0 +#define HID_KEY_KEYPAD_000 0xB1 +#define HID_KEY_THOUSANDS_SEPARATOR 0xB2 +#define HID_KEY_DECIMAL_SEPARATOR 0xB3 +#define HID_KEY_CURRENCY_UNIT 0xB4 +#define HID_KEY_CURRENCY_SUBUNIT 0xB5 +#define HID_KEY_KEYPAD_LEFT_PARENTHESIS 0xB6 +#define HID_KEY_KEYPAD_RIGHT_PARENTHESIS 0xB7 +#define HID_KEY_KEYPAD_LEFT_BRACE 0xB8 +#define HID_KEY_KEYPAD_RIGHT_BRACE 0xB9 +#define HID_KEY_KEYPAD_TAB 0xBA +#define HID_KEY_KEYPAD_BACKSPACE 0xBB +#define HID_KEY_KEYPAD_A 0xBC +#define HID_KEY_KEYPAD_B 0xBD +#define HID_KEY_KEYPAD_C 0xBE +#define HID_KEY_KEYPAD_D 0xBF +#define HID_KEY_KEYPAD_E 0xC0 +#define HID_KEY_KEYPAD_F 0xC1 +#define HID_KEY_KEYPAD_XOR 0xC2 +#define HID_KEY_KEYPAD_CARET 0xC3 +#define HID_KEY_KEYPAD_PERCENT 0xC4 +#define HID_KEY_KEYPAD_LESS_THAN 0xC5 +#define HID_KEY_KEYPAD_GREATER_THAN 0xC6 +#define HID_KEY_KEYPAD_AMPERSAND 0xC7 +#define HID_KEY_KEYPAD_DOUBLE_AMPERSAND 0xC8 +#define HID_KEY_KEYPAD_VERTICAL_BAR 0xC9 +#define HID_KEY_KEYPAD_DOUBLE_VERTICAL_BAR 0xCA +#define HID_KEY_KEYPAD_COLON 0xCB +#define HID_KEY_KEYPAD_HASH 0xCC +#define HID_KEY_KEYPAD_SPACE 0xCD +#define HID_KEY_KEYPAD_AT 0xCE +#define HID_KEY_KEYPAD_EXCLAMATION 0xCF +#define HID_KEY_KEYPAD_MEMORY_STORE 0xD0 +#define HID_KEY_KEYPAD_MEMORY_RECALL 0xD1 +#define HID_KEY_KEYPAD_MEMORY_CLEAR 0xD2 +#define HID_KEY_KEYPAD_MEMORY_ADD 0xD3 +#define HID_KEY_KEYPAD_MEMORY_SUBTRACT 0xD4 +#define HID_KEY_KEYPAD_MEMORY_MULTIPLY 0xD5 +#define HID_KEY_KEYPAD_MEMORY_DIVIDE 0xD6 +#define HID_KEY_KEYPAD_PLUS_MINUS 0xD7 +#define HID_KEY_KEYPAD_CLEAR 0xD8 +#define HID_KEY_KEYPAD_CLEAR_ENTRY 0xD9 +#define HID_KEY_KEYPAD_BINARY 0xDA +#define HID_KEY_KEYPAD_OCTAL 0xDB +#define HID_KEY_KEYPAD_DECIMAL 0xDC +#define HID_KEY_KEYPAD_HEXADECIMAL 0xDD +// RESERVED 0xDE-DF +#define HID_KEY_CONTROL_LEFT 0xE0 +#define HID_KEY_SHIFT_LEFT 0xE1 +#define HID_KEY_ALT_LEFT 0xE2 +#define HID_KEY_GUI_LEFT 0xE3 +#define HID_KEY_CONTROL_RIGHT 0xE4 +#define HID_KEY_SHIFT_RIGHT 0xE5 +#define HID_KEY_ALT_RIGHT 0xE6 +#define HID_KEY_GUI_RIGHT 0xE7 //--------------------------------------------------------------------+ -- cgit v1.3.1 From c8beaad2b18b4417ec763fc3dc85476a6480a2f4 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 18:07:22 +0200 Subject: Switch to weak default implementation. --- src/device/usbd.c | 6 +++++- src/device/usbd.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index a3f9126de..f638eb619 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -56,6 +56,10 @@ TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_is (void)in_isr; } +TU_ATTR_WEAK void tud_sof_cb(uint32_t frame_count) { + (void)frame_count; +} + //--------------------------------------------------------------------+ // Device Data //--------------------------------------------------------------------+ @@ -637,7 +641,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { if ( _usbd_sof.cb_en) { TU_LOG_USBD("\r\n"); - if ( tud_sof_cb ) tud_sof_cb(event.sof.frame_count); + tud_sof_cb(event.sof.frame_count); } break; diff --git a/src/device/usbd.h b/src/device/usbd.h index ee83ddc32..cba94fdae 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -156,7 +156,7 @@ TU_ATTR_WEAK void tud_resume_cb(void); void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); // Invoked when a new (micro) frame started -TU_ATTR_WEAK void tud_sof_cb(uint32_t frame_count); +void tud_sof_cb(uint32_t frame_count); // Invoked when received control request with VENDOR TYPE TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); -- cgit v1.3.1 From 11b5b2af51df9602b29728caf2ceb47dca61d835 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 18:34:07 +0200 Subject: Move sof status into usbd_device_t. --- src/device/usbd.c | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index f638eb619..047596924 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -76,10 +76,13 @@ typedef struct { uint8_t remote_wakeup_en : 1; // enable/disable by host uint8_t remote_wakeup_support : 1; // configuration descriptor's attribute uint8_t self_powered : 1; // configuration descriptor's attribute + + uint8_t sof_cb_en : 1; // SOF user callback enable }; volatile uint8_t cfg_num; // current active configuration (0x00 is not configured) uint8_t speed; volatile uint8_t setup_count; + uint8_t sof_ref_cnt; uint8_t itf2drv[CFG_TUD_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each @@ -279,20 +282,6 @@ TU_ATTR_ALWAYS_INLINE static inline usbd_class_driver_t const * get_driver(uint8 return driver; } -typedef struct -{ - union - { - struct - { - uint8_t count : 7; - uint8_t cb_en : 1; - }; - uint8_t value; - }; -} usbd_sof_t; - -tu_static usbd_sof_t _usbd_sof = { .value = 0 }; //--------------------------------------------------------------------+ // DCD Event @@ -403,8 +392,10 @@ bool tud_connect(void) { bool tud_sof_cb_enable(bool en) { - _usbd_sof.cb_en = en; - dcd_sof_enable(_usbd_rhport, _usbd_sof.value ? true : false); + if(_usbd_dev.sof_cb_en != en) { + _usbd_dev.sof_cb_en = en; + usbd_sof_enable(_usbd_rhport, en); + } return true; } @@ -638,8 +629,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { break; case DCD_EVENT_SOF: - if ( _usbd_sof.cb_en) - { + if ( _usbd_dev.sof_cb_en) { TU_LOG_USBD("\r\n"); tud_sof_cb(event.sof.frame_count); } @@ -1392,17 +1382,14 @@ void usbd_sof_enable(uint8_t rhport, bool en) { rhport = _usbd_rhport; // Keep track how many class instances need the SOF interrupt - if (en) - { - _usbd_sof.count++; - } - else - { - _usbd_sof.count--; + if (en) { + _usbd_dev.sof_ref_cnt++; + } else { + _usbd_dev.sof_ref_cnt--; } // Only disable SOF interrupts if all drivers switched off SOF calls and if the SOF callback isn't used - dcd_sof_enable(rhport, _usbd_sof.value ? true : false); + dcd_sof_enable(rhport, _usbd_dev.sof_ref_cnt ? true : false); } bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { -- cgit v1.3.1 From ca479d6e4b8e034dda7026fa1f229d16001d61c2 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 18:44:27 +0200 Subject: Disable SOF on configuration change. --- src/device/usbd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/device/usbd.c b/src/device/usbd.c index 047596924..e83553e0d 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -725,6 +725,9 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // already configured: need to clear all endpoints and driver first TU_LOG_USBD(" Clear current Configuration (%u) before switching\r\n", _usbd_dev.cfg_num); + // disable SOF + dcd_sof_enable(rhport, false); + // close all non-control endpoints, cancel all pending transfers if any dcd_edpt_close_all(rhport); -- cgit v1.3.1 From f09fa22bbce6139810db785940c56c5048794f31 Mon Sep 17 00:00:00 2001 From: John Toniutti Date: Thu, 9 May 2024 18:45:20 +0200 Subject: Fix redefinition --- src/class/hid/hid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index 03ef24f78..2fe922136 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -573,7 +573,7 @@ typedef enum #define HID_KEY_KEYPAD_CLEAR_ENTRY 0xD9 #define HID_KEY_KEYPAD_BINARY 0xDA #define HID_KEY_KEYPAD_OCTAL 0xDB -#define HID_KEY_KEYPAD_DECIMAL 0xDC +#define HID_KEY_KEYPAD_DECIMAL_2 0xDC #define HID_KEY_KEYPAD_HEXADECIMAL 0xDD // RESERVED 0xDE-DF #define HID_KEY_CONTROL_LEFT 0xE0 -- cgit v1.3.1 From 16cd92fbf13170a027560fa58837f209381229cd Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 21:47:22 +0200 Subject: Don't forget to queue SOF event. --- src/device/usbd.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index e83553e0d..89b819b8e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -629,7 +629,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { break; case DCD_EVENT_SOF: - if ( _usbd_dev.sof_cb_en) { + if (tu_bit_test(_usbd_dev.sof_consumer, SOF_CONSUMER_USER)) { TU_LOG_USBD("\r\n"); tud_sof_cb(event.sof.frame_count); } @@ -1127,6 +1127,14 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) break; case DCD_EVENT_SOF: + // SOF driver handler in ISR context + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { + usbd_class_driver_t const* driver = get_driver(i); + if (driver && driver->sof) { + driver->sof(event->rhport, event->sof.frame_count); + } + } + // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup // which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational if (_usbd_dev.suspended) { @@ -1136,15 +1144,10 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) queue_event(&event_resume, in_isr); } - // SOF driver handler in ISR context - for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { - usbd_class_driver_t const* driver = get_driver(i); - if (driver && driver->sof) { - driver->sof(event->rhport, event->sof.frame_count); - } + if (tu_bit_test(_usbd_dev.sof_consumer, SOF_CONSUMER_USER)) { + dcd_event_t const event_sof = {.rhport = event->rhport, .event_id = DCD_EVENT_SOF}; + queue_event(&event_sof, in_isr); } - - // skip osal queue for SOF in usbd task break; case DCD_EVENT_SETUP_RECEIVED: -- cgit v1.3.1 From 376b43906a901a878a07aca1cd364e32b839e656 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 21:55:28 +0200 Subject: Convert to bit-field since it's more reliable. --- src/class/audio/audio_device.c | 4 ++-- src/device/usbd.c | 22 ++++++++++------------ src/device/usbd_pvt.h | 11 ++++++++++- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 9ba38a20c..46db96ea9 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1835,7 +1835,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * audio->feedback.frame_shift = desc_ep->bInterval -1; // Enable SOF interrupt if callback is implemented - if (tud_audio_feedback_interval_isr) usbd_sof_enable(rhport, true); + if (tud_audio_feedback_interval_isr) usbd_sof_enable(rhport, SOF_CONSUMER_AUDIO, true); } #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -1909,7 +1909,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * break; } } - if (disable) usbd_sof_enable(rhport, false); + if (disable) usbd_sof_enable(rhport, SOF_CONSUMER_AUDIO, false); #endif #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL diff --git a/src/device/usbd.c b/src/device/usbd.c index 89b819b8e..3bd99ec40 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -76,13 +76,11 @@ typedef struct { uint8_t remote_wakeup_en : 1; // enable/disable by host uint8_t remote_wakeup_support : 1; // configuration descriptor's attribute uint8_t self_powered : 1; // configuration descriptor's attribute - - uint8_t sof_cb_en : 1; // SOF user callback enable }; volatile uint8_t cfg_num; // current active configuration (0x00 is not configured) uint8_t speed; volatile uint8_t setup_count; - uint8_t sof_ref_cnt; + volatile uint8_t sof_consumer; uint8_t itf2drv[CFG_TUD_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each @@ -392,10 +390,7 @@ bool tud_connect(void) { bool tud_sof_cb_enable(bool en) { - if(_usbd_dev.sof_cb_en != en) { - _usbd_dev.sof_cb_en = en; - usbd_sof_enable(_usbd_rhport, en); - } + usbd_sof_enable(_usbd_rhport, SOF_CONSUMER_USER, en); return true; } @@ -1384,18 +1379,21 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) { return; } -void usbd_sof_enable(uint8_t rhport, bool en) { +void usbd_sof_enable(uint8_t rhport, sof_consumer_t consumer, bool en) { rhport = _usbd_rhport; + uint8_t consumer_old = _usbd_dev.sof_consumer; // Keep track how many class instances need the SOF interrupt if (en) { - _usbd_dev.sof_ref_cnt++; + _usbd_dev.sof_consumer = tu_bit_set(_usbd_dev.sof_consumer, consumer); } else { - _usbd_dev.sof_ref_cnt--; + _usbd_dev.sof_consumer = tu_bit_clear(_usbd_dev.sof_consumer, consumer); } - // Only disable SOF interrupts if all drivers switched off SOF calls and if the SOF callback isn't used - dcd_sof_enable(rhport, _usbd_dev.sof_ref_cnt ? true : false); + // Test logically unequal + if(!!_usbd_dev.sof_consumer != !!consumer_old) { + dcd_sof_enable(rhport, _usbd_dev.sof_consumer); + } } bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 7eb504246..335d46cd8 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -35,6 +35,15 @@ #define TU_LOG_USBD(...) TU_LOG(CFG_TUD_LOG_LEVEL, __VA_ARGS__) +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ + +typedef enum { + SOF_CONSUMER_USER = 0, + SOF_CONSUMER_AUDIO, +} sof_consumer_t; + //--------------------------------------------------------------------+ // Class Driver API //--------------------------------------------------------------------+ @@ -108,7 +117,7 @@ bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr) { } // Enable SOF interrupt -void usbd_sof_enable(uint8_t rhport, bool en); +void usbd_sof_enable(uint8_t rhport, sof_consumer_t consumer, bool en); /*------------------------------------------------------------------*/ /* Helper -- cgit v1.3.1 From eea7d7b327a208fc5934feed2c19a6bfe3414b0b Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 22:00:34 +0200 Subject: Fix CI. --- src/device/usbd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 3bd99ec40..86aad2761 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1385,9 +1385,9 @@ void usbd_sof_enable(uint8_t rhport, sof_consumer_t consumer, bool en) { uint8_t consumer_old = _usbd_dev.sof_consumer; // Keep track how many class instances need the SOF interrupt if (en) { - _usbd_dev.sof_consumer = tu_bit_set(_usbd_dev.sof_consumer, consumer); + _usbd_dev.sof_consumer |= (uint8_t)(1 << consumer); } else { - _usbd_dev.sof_consumer = tu_bit_clear(_usbd_dev.sof_consumer, consumer); + _usbd_dev.sof_consumer &= (uint8_t)(~(1 << consumer)); } // Test logically unequal -- cgit v1.3.1 From 36ba42cc0f3f14b6a15fe3ee3a534319e2d89c81 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 22:57:25 +0200 Subject: Little optimization. --- src/device/usbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 86aad2761..e33f39bcf 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1391,7 +1391,7 @@ void usbd_sof_enable(uint8_t rhport, sof_consumer_t consumer, bool en) { } // Test logically unequal - if(!!_usbd_dev.sof_consumer != !!consumer_old) { + if(!_usbd_dev.sof_consumer != !consumer_old) { dcd_sof_enable(rhport, _usbd_dev.sof_consumer); } } -- cgit v1.3.1 From fc7647f9e4f06c8f56207f5ea7f34872887d099b Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 10 May 2024 00:11:04 +0200 Subject: Allow feedback EP size change. --- examples/device/uac2_speaker_fb/src/tusb_config.h | 3 +++ examples/device/uac2_speaker_fb/src/usb_descriptors.c | 4 ++-- examples/device/uac2_speaker_fb/src/usb_descriptors.h | 6 +++--- src/device/usbd.h | 10 +++++----- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/examples/device/uac2_speaker_fb/src/tusb_config.h b/examples/device/uac2_speaker_fb/src/tusb_config.h index 497104541..1cc1031c1 100644 --- a/examples/device/uac2_speaker_fb/src/tusb_config.h +++ b/examples/device/uac2_speaker_fb/src/tusb_config.h @@ -122,6 +122,9 @@ extern "C" { #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_SPEAKER_STEREO_FB_DESC_LEN +// Enable if Full-Speed on OSX, also set feedback EP size to 3 +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 + // Audio format type I specifications #if defined(__RX__) #define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 48000 diff --git a/examples/device/uac2_speaker_fb/src/usb_descriptors.c b/examples/device/uac2_speaker_fb/src/usb_descriptors.c index 864b689ff..fa307674d 100644 --- a/examples/device/uac2_speaker_fb/src/usb_descriptors.c +++ b/examples/device/uac2_speaker_fb/src/usb_descriptors.c @@ -149,8 +149,8 @@ uint8_t const desc_configuration[] = // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), - // Interface number, string index, byte per sample, bit per sample, EP Out, EP size, EP feedback - TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR(0, 4, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX, EPNUM_AUDIO_OUT, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX, EPNUM_AUDIO_FB | 0x80), + // Interface number, string index, byte per sample, bit per sample, EP Out, EP size, EP feedback, feedback EP size, + TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR(0, 4, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX, EPNUM_AUDIO_OUT, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX, EPNUM_AUDIO_FB | 0x80, 4), #if CFG_AUDIO_DEBUG // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval diff --git a/examples/device/uac2_speaker_fb/src/usb_descriptors.h b/examples/device/uac2_speaker_fb/src/usb_descriptors.h index 8157f02a0..9511bf797 100644 --- a/examples/device/uac2_speaker_fb/src/usb_descriptors.h +++ b/examples/device/uac2_speaker_fb/src/usb_descriptors.h @@ -47,7 +47,7 @@ + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\ + TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN) -#define TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epsize, _epfb) \ +#define TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epoutsize, _epfb, _epfbsize) \ /* Standard Interface Association Descriptor (IAD) */\ TUD_AUDIO_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ @@ -73,10 +73,10 @@ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epoutsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_interval*/ TUD_OPT_HIGH_SPEED ? 4 : 1)\ + TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_epsize*/ _epfbsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 4 : 1)\ #endif diff --git a/src/device/usbd.h b/src/device/usbd.h index d6f6f923d..3caaaca25 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -428,8 +428,8 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */ #define TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN 7 -#define TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(_ep, _interval) \ - TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN, TUSB_DESC_ENDPOINT, _ep, (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_NO_SYNC | (uint8_t)TUSB_ISO_EP_ATT_EXPLICIT_FB), U16_TO_U8S_LE(4), _interval +#define TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(_ep, _epsize, _interval) \ + TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN, TUSB_DESC_ENDPOINT, _ep, (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_NO_SYNC | (uint8_t)TUSB_ISO_EP_ATT_EXPLICIT_FB), U16_TO_U8S_LE(_epsize), _interval // AUDIO simple descriptor (UAC2) for 1 microphone input // - 1 Input Terminal, 1 Feature Unit (Mute and Volume Control), 1 Output Terminal, 1 Clock Source @@ -547,7 +547,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\ + TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN) -#define TUD_AUDIO_SPEAKER_MONO_FB_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epsize, _epfb) \ +#define TUD_AUDIO_SPEAKER_MONO_FB_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epoutsize, _epfb, _epfbsize) \ /* Standard Interface Association Descriptor (IAD) */\ TUD_AUDIO_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ @@ -573,11 +573,11 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epoutsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_interval*/ 1) + TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_epsize*/ _epfbsize, /*_interval*/ 1) // Calculate wMaxPacketSize of Endpoints #define TUD_AUDIO_EP_SIZE(_maxFrequency, _nBytesPerSample, _nChannels) \ -- cgit v1.3.1 From 2f5db37c1aea932845c2de8fe5bb4b1b08b24722 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 10 May 2024 10:30:47 +0700 Subject: use argparse instead of click to fix cifuzz.yml --- .github/workflows/cifuzz.yml | 1 - tools/get_deps.py | 25 +++++++++++++++---------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index faa0f911c..622d261a0 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -12,7 +12,6 @@ on: - '**.h' jobs: Fuzzing: - if: false runs-on: ubuntu-latest steps: - name: Build Fuzzers diff --git a/tools/get_deps.py b/tools/get_deps.py index bca38fc80..2359b4bd0 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -1,4 +1,4 @@ -import click +import argparse import sys import subprocess from pathlib import Path @@ -238,28 +238,33 @@ def find_family(board): return None -@click.command() -@click.argument('family', nargs=-1, required=False) -@click.option('-b', '--board', multiple=True, default=None, help='Boards to fetch') -def main(family, board): - if len(family) == 0 and len(board) == 0: +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('families', nargs='*', default=[], help='Families to fetch') + parser.add_argument('-b', '--board', action='append', default=[], help='Boards to fetch') + args = parser.parse_args() + + families = args.families + board = args.board + + if len(families) == 0 and len(board) == 0: print("Please specify family or board to fetch") return status = 0 deps = list(deps_mandatory.keys()) - if 'all' in family: + if 'all' in families: deps += deps_optional.keys() else: - family = list(family) + families = list(families) if board is not None: for b in board: f = find_family(b) if f is not None: - family.append(f) + families.append(f) - for f in family: + for f in families: for d in deps_optional: if f in deps_optional[d][2]: deps.append(d) -- cgit v1.3.1 From 15e2ccf1b3b7c53a90550e637285c00c88a4a3fe Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 10 May 2024 12:44:54 +0700 Subject: CircleCI Commit --- .circleci/config.yml | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..e8a81dbb6 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,39 @@ +# This config was automatically generated from your source code +# Stacks detected: cicd:github-actions:.github/workflows,deps:python:docs +version: 2.1 +orbs: + python: circleci/python@2 +jobs: + test-python: + # Install dependencies and run tests + docker: + - image: cimg/python:3.8-node + working_directory: ~/project/docs + steps: + - checkout: + path: ~/project + - python/install-packages + - run: + name: Run tests + command: pytest --junitxml=junit.xml || ((($? == 5)) && echo 'Did not find any tests to run.') + - store_test_results: + path: junit.xml + deploy: + # This is an example deploy job, not actually used by the workflow + docker: + - image: cimg/base:stable + steps: + # Replace this with steps to deploy to users + - run: + name: deploy + command: '#e.g. ./deploy.sh' + - run: + name: found github actions config + command: ':' +workflows: + build-and-test: + jobs: + - test-python + # - deploy: + # requires: + # - test-python -- cgit v1.3.1 From 8d63d9368edaec0385af20d615a0acba51f77beb Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 10 May 2024 13:00:19 +0700 Subject: Add .circleci/config.yml --- .circleci/config.yml | 56 ++++++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e8a81dbb6..62291703e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,39 +1,31 @@ -# This config was automatically generated from your source code -# Stacks detected: cicd:github-actions:.github/workflows,deps:python:docs +# Use the latest 2.1 version of CircleCI pipeline process engine. +# See: https://circleci.com/docs/configuration-reference version: 2.1 -orbs: - python: circleci/python@2 + +# Define a job to be invoked later in a workflow. +# See: https://circleci.com/docs/jobs-steps/#jobs-overview & https://circleci.com/docs/configuration-reference/#jobs jobs: - test-python: - # Install dependencies and run tests + say-hello: + # Specify the execution environment. You can specify an image from Docker Hub or use one of our convenience images from CircleCI's Developer Hub. + # See: https://circleci.com/docs/executor-intro/ & https://circleci.com/docs/configuration-reference/#executor-job docker: - - image: cimg/python:3.8-node - working_directory: ~/project/docs + # Specify the version you desire here + # See: https://circleci.com/developer/images/image/cimg/base + - image: cimg/base:current + + # Add steps to the job + # See: https://circleci.com/docs/jobs-steps/#steps-overview & https://circleci.com/docs/configuration-reference/#steps steps: - - checkout: - path: ~/project - - python/install-packages + # Checkout the code as the first step. + - checkout - run: - name: Run tests - command: pytest --junitxml=junit.xml || ((($? == 5)) && echo 'Did not find any tests to run.') - - store_test_results: - path: junit.xml - deploy: - # This is an example deploy job, not actually used by the workflow - docker: - - image: cimg/base:stable - steps: - # Replace this with steps to deploy to users - - run: - name: deploy - command: '#e.g. ./deploy.sh' - - run: - name: found github actions config - command: ':' + name: "Say hello" + command: "echo Hello, World!" + +# Orchestrate jobs using workflows +# See: https://circleci.com/docs/workflows/ & https://circleci.com/docs/configuration-reference/#workflows workflows: - build-and-test: + say-hello-workflow: # This is the name of the workflow, feel free to change it to better match your workflow. + # Inside the workflow, you define the jobs you want to run. jobs: - - test-python - # - deploy: - # requires: - # - test-python + - say-hello \ No newline at end of file -- cgit v1.3.1 From 81ceb837b9feb3971056196f6a67234c4012352b Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 10 May 2024 17:53:26 +0700 Subject: Update config.yml --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 62291703e..d5d401c51 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -28,4 +28,4 @@ workflows: say-hello-workflow: # This is the name of the workflow, feel free to change it to better match your workflow. # Inside the workflow, you define the jobs you want to run. jobs: - - say-hello \ No newline at end of file + - say-hello -- cgit v1.3.1 From 3e2ea7750681b27238043c7158ff5508f01914a3 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 10 May 2024 18:55:43 +0700 Subject: More ci tweak (#2636) * change concurrency group to ${{ github.workflow }}-${{ github.ref }} * use argparse for build.py hil_test.py, remove the need to install click * move ci win/mac to build_cmake.yml * rename build_family.yml to build_util.yml * build_util.yml support esp32 * integrate build-espressif into build.yml * build.py support make with --board option * add get_deps action * update hil test to reuse action --- .github/actions/get_deps/action.yml | 29 +++++++ .github/actions/prepare_build/action.yml | 30 ------- .github/actions/setup_toolchain/action.yml | 18 ++++- .github/workflows/build_cmake.yml | 46 +++++++++-- .github/workflows/build_esp.yml | 109 ------------------------- .github/workflows/build_family.yml | 64 --------------- .github/workflows/build_iar.yml | 2 +- .github/workflows/build_renesas.yml | 3 +- .github/workflows/build_util.yml | 59 ++++++++++++++ .github/workflows/build_win_mac.yml | 56 ------------- .github/workflows/ci_set_matrix.py | 2 +- .github/workflows/hil_test.yml | 121 ++++++++++++++++++++-------- .github/workflows/pre-commit.yml | 3 +- examples/device/net_lwip_webserver/skip.txt | 4 +- examples/device/video_capture_2ch/skip.txt | 2 + examples/host/cdc_msc_hid_freertos/only.txt | 1 - hw/bsp/lpc17/family.mk | 2 +- hw/bsp/lpc40/family.mk | 2 + src/class/net/ncm_device.c | 16 ++-- test/hil/hil_test.py | 19 +++-- test/hil/pi4.json | 10 +++ test/hil/pi4_esp32.json | 14 ---- tools/build.py | 46 +++++++---- tools/build_esp32.py | 106 ------------------------ tools/get_deps.py | 11 ++- 25 files changed, 314 insertions(+), 461 deletions(-) create mode 100644 .github/actions/get_deps/action.yml delete mode 100644 .github/actions/prepare_build/action.yml delete mode 100644 .github/workflows/build_esp.yml delete mode 100644 .github/workflows/build_family.yml create mode 100644 .github/workflows/build_util.yml delete mode 100644 .github/workflows/build_win_mac.yml delete mode 100644 test/hil/pi4_esp32.json delete mode 100644 tools/build_esp32.py diff --git a/.github/actions/get_deps/action.yml b/.github/actions/get_deps/action.yml new file mode 100644 index 000000000..38b44a70e --- /dev/null +++ b/.github/actions/get_deps/action.yml @@ -0,0 +1,29 @@ +name: Get dependencies + +inputs: + arg: + required: true + type: string + +runs: + using: "composite" + steps: + - name: Checkout pico-sdk for rp2040 + if: contains(inputs.arg, 'rp2040') || contains(inputs.arg, 'raspberry_pi_pico') + uses: actions/checkout@v4 + with: + repository: raspberrypi/pico-sdk + ref: develop + path: pico-sdk + + - name: Linux dependencies + if: runner.os == 'Linux' + run: | + sudo apt install -y ninja-build + shell: bash + + - name: Get Dependencies + run: | + python3 tools/get_deps.py ${{ inputs.arg }} + echo "PICO_SDK_PATH=${{ github.workspace }}/pico-sdk" >> $GITHUB_ENV + shell: bash diff --git a/.github/actions/prepare_build/action.yml b/.github/actions/prepare_build/action.yml deleted file mode 100644 index 5f2c544c1..000000000 --- a/.github/actions/prepare_build/action.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Prepare to build - -inputs: - family: - required: true - type: string - -runs: - using: "composite" - steps: - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Checkout pico-sdk for rp2040 - if: contains(inputs.family, 'rp2040') - uses: actions/checkout@v4 - with: - repository: raspberrypi/pico-sdk - ref: develop - path: pico-sdk - - - name: Get Dependencies - run: | - sudo apt install -y ninja-build - pip install click - python3 tools/get_deps.py ${{ inputs.family }} - echo >> $GITHUB_ENV "PICO_SDK_PATH=$GITHUB_WORKSPACE/pico-sdk" - shell: bash diff --git a/.github/actions/setup_toolchain/action.yml b/.github/actions/setup_toolchain/action.yml index b59ece116..e6c79e7dd 100644 --- a/.github/actions/setup_toolchain/action.yml +++ b/.github/actions/setup_toolchain/action.yml @@ -8,6 +8,11 @@ inputs: required: false type: string +outputs: + build_option: + description: 'Build option for the toolchain e.g --toolchain clang' + value: ${{ steps.set-toolchain-option.outputs.build_option }} + runs: using: "composite" steps: @@ -19,7 +24,7 @@ runs: - name: Pull ESP-IDF docker if: inputs.toolchain == 'esp-idf' - run: docker pull espressif/idf:latest + run: docker pull espressif/idf:${{ inputs.toolchain_url }} shell: bash - name: Download Toolchain @@ -29,3 +34,14 @@ runs: uses: ./.github/actions/setup_toolchain/download with: toolchain_url: ${{ inputs.toolchain_url }} + + - name: Set toolchain option + id: set-toolchain-option + run: | + BUILD_OPTION="" + if [[ "${{ inputs.toolchain }}" == *"clang"* ]]; then + BUILD_OPTION="--toolchain clang" + fi + echo "build_option=$BUILD_OPTION" + echo "build_option=$BUILD_OPTION" >> $GITHUB_OUTPUT + shell: bash diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index b62a0e9bd..4723cf8d9 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -12,6 +12,7 @@ on: - 'tools/build.py' - '.github/actions/**' - '.github/workflows/build_cmake.yml' + - '.github/workflows/build_util.yml' - '.github/workflows/ci_set_matrix.py' pull_request: branches: [ master ] @@ -24,9 +25,10 @@ on: - 'tools/build.py' - '.github/actions/**' - '.github/workflows/build_cmake.yml' + - '.github/workflows/build_util.yml' - '.github/workflows/ci_set_matrix.py' concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: @@ -55,7 +57,7 @@ jobs: # --------------------------------------- cmake: needs: set-matrix - uses: ./.github/workflows/build_family.yml + uses: ./.github/workflows/build_util.yml strategy: fail-fast: false matrix: @@ -69,14 +71,14 @@ jobs: build-system: 'cmake' toolchain: ${{ matrix.toolchain }} toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} - build-family: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} + build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} # --------------------------------------- # Build Make # --------------------------------------- make: needs: set-matrix - uses: ./.github/workflows/build_family.yml + uses: ./.github/workflows/build_util.yml strategy: fail-fast: false matrix: @@ -90,4 +92,38 @@ jobs: build-system: 'make' toolchain: ${{ matrix.toolchain }} toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} - build-family: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} + build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} + + # --------------------------------------- + # Build Make on Windows/MacOS + # --------------------------------------- + make-os: + uses: ./.github/workflows/build_util.yml + strategy: + fail-fast: false + matrix: + os: [windows-latest, macos-latest] + with: + os: ${{ matrix.os }} + build-system: 'make' + toolchain: 'arm-gcc' + build-args: '["-bstm32f411disco"]' + + # --------------------------------------- + # Build Espressif + # --------------------------------------- + espressif: + uses: ./.github/workflows/build_util.yml + strategy: + fail-fast: false + matrix: + board: + # ESP32-S2 + - 'espressif_kaluga_1' + # ESP32-S3 skip since devkitm is also compiled in hil-test workflow + #- 'espressif_s3_devkitm' + with: + build-system: 'cmake' + toolchain: 'esp-idf' + toolchain_url: 'v5.1.1' + build-args: '["-b${{ matrix.board }}"]' diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml deleted file mode 100644 index 66fa8548e..000000000 --- a/.github/workflows/build_esp.yml +++ /dev/null @@ -1,109 +0,0 @@ -name: Build ESP - -on: - workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'test/hil/**' - - '.github/workflows/build_esp.yml' - pull_request: - branches: [ master ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'test/hil/**' - - '.github/workflows/build_esp.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build-esp: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - board: - # ESP32-S2 - - 'espressif_kaluga_1' - # ESP32-S3 - - 'espressif_s3_devkitm' - steps: - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Setup Toolchain - uses: ./.github/actions/setup_toolchain - with: - toolchain: 'esp-idf' - - - name: Build - run: docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python3 tools/build.py -b ${{ matrix.board }} - - - name: Upload Artifacts for Hardware Testing - if: matrix.board == 'espressif_s3_devkitm' && github.repository_owner == 'hathach' - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.board }} - path: | - cmake-build/cmake-build-${{ matrix.board }}/*/*/bootloader/bootloader.bin - cmake-build/cmake-build-${{ matrix.board }}/*/*/*.bin - cmake-build/cmake-build-${{ matrix.board }}/*/*/partition_table/partition-table.bin - cmake-build/cmake-build-${{ matrix.board }}/*/*/config.env - cmake-build/cmake-build-${{ matrix.board }}/*/*/flash_args - - # --------------------------------------- - # Hardware in the loop (HIL) - # Current self-hosted instance is running on an RPI4. For attached hardware checkout hil_pi4.json - # --------------------------------------- - hil-test: - # run only with hathach's commit due to limited resource on RPI4 - if: github.repository_owner == 'hathach' - needs: build-esp - runs-on: [self-hosted, esp32s3, hardware-in-the-loop] - strategy: - fail-fast: false - matrix: - board: - - 'espressif_s3_devkitm' - steps: - - name: Clean workspace - run: | - echo "Cleaning up previous run" - rm -rf "${{ github.workspace }}" - mkdir -p "${{ github.workspace }}" - - # USB bus on rpi4 is not stable, reset it before testing - - name: Reset USB bus - run: | - lsusb - lsusb -t - # reset VIA Labs 2.0 hub - sudo usbreset 001/002 - - - name: Checkout test/hil - uses: actions/checkout@v4 - with: - sparse-checkout: test/hil - - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - name: ${{ matrix.board }} - path: cmake-build/cmake-build-${{ matrix.board }} - - - name: Test on actual hardware - run: | - python3 test/hil/hil_test.py --board ${{ matrix.board }} pi4_esp32.json diff --git a/.github/workflows/build_family.yml b/.github/workflows/build_family.yml deleted file mode 100644 index 2e89267a3..000000000 --- a/.github/workflows/build_family.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Build family - -on: - workflow_call: - inputs: - build-system: - required: true - type: string - toolchain: - required: true - type: string - toolchain_url: - required: true - type: string - build-family: - required: true - type: string - -jobs: - family: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - family: ${{ fromJSON(inputs.build-family) }} - steps: - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Setup Toolchain - uses: ./.github/actions/setup_toolchain - with: - toolchain: ${{ inputs.toolchain }} - toolchain_url: ${{ inputs.toolchain_url }} - - - name: Checkout pico-sdk for rp2040 - if: contains(matrix.family, 'rp2040') - uses: actions/checkout@v4 - with: - repository: raspberrypi/pico-sdk - ref: develop - path: pico-sdk - - - name: Get Dependencies - run: | - sudo apt install -y ninja-build - pip install click - python3 tools/get_deps.py ${{ matrix.family }} - - - name: Build - run: | - OPTION="" - if [[ "${{ inputs.toolchain }}" == *"clang"* ]]; then - OPTION="--toolchain clang" - fi - echo "OPTION=$OPTION" - python tools/build.py -s ${{ inputs.build-system }} $OPTION ${{ matrix.family }} - env: - PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk diff --git a/.github/workflows/build_iar.yml b/.github/workflows/build_iar.yml index c4a7f96b7..34dbda192 100644 --- a/.github/workflows/build_iar.yml +++ b/.github/workflows/build_iar.yml @@ -23,7 +23,7 @@ on: - '.github/workflows/build_iar.yml' concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml index 8c83bdbbf..1be49344f 100644 --- a/.github/workflows/build_renesas.yml +++ b/.github/workflows/build_renesas.yml @@ -21,7 +21,7 @@ on: - '.github/workflows/build_renesas.yml' concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: @@ -65,7 +65,6 @@ jobs: - name: Get Dependencies run: | - pip install click python3 tools/get_deps.py ${{ matrix.family }} - name: Build diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml new file mode 100644 index 000000000..f8ad1900c --- /dev/null +++ b/.github/workflows/build_util.yml @@ -0,0 +1,59 @@ +name: Reusable build util + +on: + workflow_call: + inputs: + build-system: + required: true + type: string + toolchain: + required: true + type: string + toolchain_url: + required: false + type: string + build-args: + required: true + type: string + os: + required: false + type: string + default: 'ubuntu-latest' + +jobs: + family: + runs-on: ${{ inputs.os }} + strategy: + fail-fast: false + matrix: + arg: ${{ fromJSON(inputs.build-args) }} + steps: + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Setup Toolchain + id: setup-toolchain + uses: ./.github/actions/setup_toolchain + with: + toolchain: ${{ inputs.toolchain }} + toolchain_url: ${{ inputs.toolchain_url }} + + - name: Get Dependencies + uses: ./.github/actions/get_deps + with: + arg: ${{ matrix.arg }} + + - name: Build + if: inputs.toolchain != 'esp-idf' + run: | + python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ matrix.arg }} + + - name: Build using ESP-IDF docker + if: inputs.toolchain == 'esp-idf' + run: | + docker run --rm -v $PWD:/project -w /project espressif/idf:${{ inputs.toolchain_url }} python3 tools/build.py ${{ matrix.arg }} diff --git a/.github/workflows/build_win_mac.yml b/.github/workflows/build_win_mac.yml deleted file mode 100644 index 35328aa32..000000000 --- a/.github/workflows/build_win_mac.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Build Windows/MacOS - -on: - workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/build_win_mac.yml' - pull_request: - branches: [ master ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/build_win_mac.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - # --------------------------------------- - # Build ARM family - # --------------------------------------- - build-arm: - strategy: - fail-fast: false - matrix: - os: [windows-latest, macos-latest] - runs-on: ${{ matrix.os }} - - steps: - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Install ARM GCC - uses: carlosperate/arm-none-eabi-gcc-action@v1 - with: - release: '10.3-2021.10' - - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Get Dependencies - run: | - pip install click - python3 tools/get_deps.py stm32f4 - - - name: Build - run: python3 tools/build.py -s make stm32f2 diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 2a17be6a1..ea758d917 100644 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -16,7 +16,7 @@ family_list = { "ch32v307 fomu gd32vf103": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"], - "lpc11 lpc13 lpc15": ["arm-gcc"], + "lpc11 lpc13 lpc15": ["arm-gcc", "arm-clang"], "lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"], "lpc51 lpc54 lpc55": ["arm-gcc", "arm-clang"], "mcx": ["arm-gcc"], diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index 024ab969d..796ff32dc 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -24,15 +24,18 @@ on: - '.github/actions/**' - '.github/workflows/hil_test.yml' concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: + # --------------------------------------- + # Build Non Espressif + # --------------------------------------- build: if: github.repository_owner == 'hathach' runs-on: ubuntu-latest outputs: - BOARD_LIST: ${{ steps.parse_hil_json.outputs.BOARD_LIST }} + BOARDS_LIST: ${{ steps.parse_hil_json.outputs.BOARDS_LIST }} steps: - name: Checkout TinyUSB uses: actions/checkout@v4 @@ -42,38 +45,29 @@ jobs: with: python-version: '3.x' - - name: Install ARM GCC - uses: carlosperate/arm-none-eabi-gcc-action@v1 - with: - release: '12.3.Rel1' - - name: Parse HIL json id: parse_hil_json run: | sudo apt install -y jq - BOARD_LIST=$(jq -r '.boards[] | "-b " + .name' test/hil/pi4.json | tr '\n' ' ') - echo "BOARD_LIST=$BOARD_LIST" - echo >> $GITHUB_ENV "BOARD_LIST=$BOARD_LIST" - echo >> $GITHUB_OUTPUT "BOARD_LIST=$BOARD_LIST" - - name: Checkout pico-sdk for rp2040 - uses: actions/checkout@v4 + # Non-Espresif boards + BOARDS_LIST=$(jq -r '.boards[] | select(.flasher != "esptool") | "-b " + .name' test/hil/pi4.json | tr '\n' ' ') + echo "BOARDS_LIST=$BOARDS_LIST" + echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV + echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT + + - name: Setup ARM Toolchain + uses: ./.github/actions/setup_toolchain with: - repository: raspberrypi/pico-sdk - ref: develop - path: pico-sdk + toolchain: 'arm-gcc' - name: Get Dependencies - run: | - pip install click - sudo apt install -y ninja-build - python3 tools/get_deps.py $BOARD_LIST + uses: ./.github/actions/get_deps + with: + arg: ${{ env.BOARDS_LIST }} - name: Build - run: | - python tools/build.py $BOARD_LIST - env: - PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk + run: python tools/build.py $BOARDS_LIST - name: Upload Artifacts for Hardware Testing uses: actions/upload-artifact@v4 @@ -83,16 +77,71 @@ jobs: cmake-build/cmake-build-*/*/*/*.elf cmake-build/cmake-build-*/*/*/*.bin + # --------------------------------------- + # Build Espressif + # --------------------------------------- + build-esp: + runs-on: ubuntu-latest + outputs: + BOARDS_LIST: ${{ steps.parse_hil_json.outputs.BOARDS_LIST }} + steps: + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Parse HIL json + id: parse_hil_json + run: | + sudo apt install -y jq + # Espressif boards + BOARDS_LIST=$(jq -r '.boards[] | select(.flasher == "esptool") | "-b " + .name' test/hil/pi4.json | tr '\n' ' ') + echo "BOARDS_LIST=$BOARDS_LIST" + echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV + echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT + + - name: Setup ESP-IDF + if: env.BOARDS_LIST != '' + uses: ./.github/actions/setup_toolchain + with: + toolchain: 'esp-idf' + toolchain_url: 'v5.1.1' + + - name: Get Dependencies + uses: ./.github/actions/get_deps + with: + arg: ${{ env.BOARDS_LIST }} + + - name: Build Espressif + if: env.BOARDS_LIST != '' + run: docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python3 tools/build.py $BOARDS_LIST + + - name: Upload Artifacts for Hardware Testing + uses: actions/upload-artifact@v4 + with: + name: hil_pi4_esp + path: | + cmake-build/cmake-build-*/*/*/*.bin + cmake-build/cmake-build-*/*/*/bootloader/bootloader.bin + cmake-build/cmake-build-*/*/*/partition_table/partition-table.bin + cmake-build/cmake-build-*/*/*/config.env + cmake-build/cmake-build-*/*/*/flash_args + # --------------------------------------- # Hardware in the loop (HIL) - # Current self-hosted instance is running on an RPI4. For attached hardware checkout hil_pi4.json + # Current self-hosted instance is running on an RPI4. For attached hardware checkout test/hil/pi4.json # --------------------------------------- hil-pi4: if: github.repository_owner == 'hathach' - needs: build - runs-on: [self-hosted, rp2040, nrf52840, hardware-in-the-loop] + needs: + - build + - build-esp + runs-on: [self-hosted, rp2040, nrf52840, esp32s3, hardware-in-the-loop] env: - BOARD_LIST: ${{ needs.build.outputs.BOARD_LIST }} + BOARDS_LIST: "${{ needs.build.outputs.BOARDS_LIST }} ${{ needs.build-esp.outputs.BOARDS_LIST }}" steps: - name: Clean workspace run: | @@ -103,8 +152,7 @@ jobs: # USB bus on rpi4 is not stable, reset it before testing - name: Reset USB bus run: | - lsusb - lsusb -t + # lsusb -t # reset VIA Labs 2.0 hub sudo usbreset 001/002 @@ -119,7 +167,16 @@ jobs: name: hil_pi4 path: cmake-build + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + name: hil_pi4_esp + path: cmake-build + - name: Test on actual hardware run: | - echo "BOARD_LIST=$BOARD_LIST" - python3 test/hil/hil_test.py $BOARD_LIST pi4.json + echo "BOARDS_LIST=$BOARDS_LIST" + echo "::group::{cmake-build contents}" + tree cmake-build + echo "::endgroup::" + python3 test/hil/hil_test.py $BOARDS_LIST pi4.json diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 6b3151702..d1ffe6ca1 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -7,7 +7,7 @@ on: branches: [ master ] concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: @@ -38,7 +38,6 @@ jobs: - name: Build Fuzzer run: | - pip install click export CC=clang export CXX=clang++ fuzz_harness=$(ls -d test/fuzz/device/*/) diff --git a/examples/device/net_lwip_webserver/skip.txt b/examples/device/net_lwip_webserver/skip.txt index bb3ff7885..43cdab71a 100644 --- a/examples/device/net_lwip_webserver/skip.txt +++ b/examples/device/net_lwip_webserver/skip.txt @@ -9,6 +9,8 @@ mcu:STM32F0 mcu:KINETIS_KL family:broadcom_64bit family:broadcom_32bit +family:espressif board:curiosity_nano board:frdm_kl25z -family:espressif +# lpc55 has weird error 'ncm_interface' causes a section type conflict with 'ntb_parameters' +family:lpc55 diff --git a/examples/device/video_capture_2ch/skip.txt b/examples/device/video_capture_2ch/skip.txt index 15c176a2a..86697899b 100644 --- a/examples/device/video_capture_2ch/skip.txt +++ b/examples/device/video_capture_2ch/skip.txt @@ -12,3 +12,5 @@ board:lpcxpresso11u68 board:stm32f303disco board:stm32l412nucleo board:ek_tm4c123gxl +board:uno_r4 +board:ra4m1_ek diff --git a/examples/host/cdc_msc_hid_freertos/only.txt b/examples/host/cdc_msc_hid_freertos/only.txt index 81d993ffa..1e0e60075 100644 --- a/examples/host/cdc_msc_hid_freertos/only.txt +++ b/examples/host/cdc_msc_hid_freertos/only.txt @@ -8,5 +8,4 @@ mcu:MIMXRT10XX mcu:MIMXRT11XX mcu:MSP432E4 mcu:RX65X -mcu:RAXXX mcu:MAX3421 diff --git a/hw/bsp/lpc17/family.mk b/hw/bsp/lpc17/family.mk index 84ed95648..d719a47b7 100644 --- a/hw/bsp/lpc17/family.mk +++ b/hw/bsp/lpc17/family.mk @@ -22,8 +22,8 @@ LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/nxp/lpc17_40/dcd_lpc17_40.c \ - src/portable/ohci/ohci.c \ src/portable/nxp/lpc17_40/hcd_lpc17_40.c \ + src/portable/ohci/ohci.c \ $(MCU_DIR)/../gcc/cr_startup_lpc175x_6x.c \ $(MCU_DIR)/src/chip_17xx_40xx.c \ $(MCU_DIR)/src/clock_17xx_40xx.c \ diff --git a/hw/bsp/lpc40/family.mk b/hw/bsp/lpc40/family.mk index 79d868f35..ef9fe57b2 100644 --- a/hw/bsp/lpc40/family.mk +++ b/hw/bsp/lpc40/family.mk @@ -20,6 +20,8 @@ LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs # All source paths should be relative to the top level. SRC_C += \ src/portable/nxp/lpc17_40/dcd_lpc17_40.c \ + src/portable/nxp/lpc17_40/hcd_lpc17_40.c \ + src/portable/ohci/ohci.c \ $(MCU_DIR)/../gcc/cr_startup_lpc40xx.c \ $(MCU_DIR)/src/chip_17xx_40xx.c \ $(MCU_DIR)/src/clock_17xx_40xx.c \ diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 4b237e4cf..64aba011a 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -112,7 +112,7 @@ typedef struct { bool notification_xmit_is_running; // notification is currently transmitted } ncm_interface_t; -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static ncm_interface_t ncm_interface; +CFG_TUD_MEM_SECTION CFG_TUD_MEM_ALIGN tu_static ncm_interface_t ncm_interface; /** * This is the NTB parameter structure @@ -120,7 +120,7 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static ncm_interface_t ncm_interface; * \attention * We are lucky, that byte order is correct */ -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { +CFG_TUD_MEM_SECTION CFG_TUD_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { .wLength = sizeof(ntb_parameters_t), .bmNtbFormatsSupported = 0x01,// 16-bit NTB supported .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, @@ -285,7 +285,7 @@ static xmit_ntb_t *xmit_get_next_ready_ntb(void) { * This must be called from netd_xfer_cb() so that ep_in is ready */ static bool xmit_insert_required_zlp(uint8_t rhport, uint32_t xferred_bytes) { - TU_LOG_DRV("xmit_insert_required_zlp(%d,%d)\n", rhport, xferred_bytes); + TU_LOG_DRV("xmit_insert_required_zlp(%d,%ld)\n", rhport, xferred_bytes); if (xferred_bytes == 0 || xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE != 0) { return false; @@ -521,11 +521,11 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) { return false; } if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t)) { - TU_LOG_DRV("(EE) ill min len: %d\n", len); + TU_LOG_DRV("(EE) ill min len: %lu\n", len); return false; } if (nth16->wBlockLength > len) { - TU_LOG_DRV("(EE) ill block length: %d > %d\n", nth16->wBlockLength, len); + TU_LOG_DRV("(EE) ill block length: %d > %lu\n", nth16->wBlockLength, len); return false; } if (nth16->wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { @@ -533,7 +533,7 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) { return false; } if (nth16->wNdpIndex < sizeof(nth16) || nth16->wNdpIndex > len - (sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t))) { - TU_LOG_DRV("(EE) ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); + TU_LOG_DRV("(EE) ill position of first ndp: %d (%lu)\n", nth16->wNdpIndex, len); return false; } @@ -567,11 +567,11 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) { while (ndp16_datagram[ndx].wDatagramIndex != 0 && ndp16_datagram[ndx].wDatagramLength != 0) { TU_LOG_DRV(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); if (ndp16_datagram[ndx].wDatagramIndex > len) { - TU_LOG_DRV("(EE) ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); + TU_LOG_DRV("(EE) ill start of datagram[%d]: %d (%lu)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); return false; } if (ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength > len) { - TU_LOG_DRV("(EE) ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); + TU_LOG_DRV("(EE) ill end of datagram[%d]: %d (%lu)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); return false; } ++ndx; diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index dffb81765..c2699cc6f 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -25,10 +25,10 @@ # ACTION=="add", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", MODE="0666", PROGRAM="/bin/sh -c 'echo $$ID_SERIAL_SHORT | rev | cut -c -8 | rev'", SYMLINK+="ttyUSB_%c.%s{bInterfaceNumber}" # ACTION=="add", SUBSYSTEM=="block", SUBSYSTEMS=="usb", ENV{ID_FS_USAGE}=="filesystem", MODE="0666", PROGRAM="/bin/sh -c 'echo $$ID_SERIAL_SHORT | rev | cut -c -8 | rev'", RUN{program}+="/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode /media/blkUSB_%c.%s{bInterfaceNumber}" +import argparse import os import sys import time -import click import serial import subprocess import json @@ -318,13 +318,18 @@ def test_hid_composite_freertos(id): # ------------------------------------------------------------- # Main # ------------------------------------------------------------- -@click.command() -@click.argument('config_file') -@click.option('-b', '--board', multiple=True, default=None, help='Boards to test, all if not specified') -def main(config_file, board): +def main(): """ Hardware test on specified boards """ + parser = argparse.ArgumentParser() + parser.add_argument('config_file', help='Configuration JSON file') + parser.add_argument('-b', '--board', action='append', default=[], help='Boards to test, all if not specified') + args = parser.parse_args() + + config_file = args.config_file + boards = args.board + config_file = os.path.join(os.path.dirname(__file__), config_file) with open(config_file) as f: config = json.load(f) @@ -334,10 +339,10 @@ def main(config_file, board): 'cdc_dual_ports', 'cdc_msc', 'dfu', 'dfu_runtime', 'hid_boot_interface', ] - if len(board) == 0: + if len(boards) == 0: config_boards = config['boards'] else: - config_boards = [e for e in config['boards'] if e['name'] in board] + config_boards = [e for e in config['boards'] if e['name'] in boards] for item in config_boards: name = item['name'] diff --git a/test/hil/pi4.json b/test/hil/pi4.json index 04329bb64..bdb8a5fa5 100644 --- a/test/hil/pi4.json +++ b/test/hil/pi4.json @@ -22,6 +22,16 @@ "flasher_product": "ItsyBitsy M4 Express", "flasher_reset_pin": "2", "flasher_args": "--offset 0x4000" + }, + { + "name": "espressif_s3_devkitm", + "uid": "84F703C084E4", + "tests": [ + "cdc_msc_freertos", "hid_composite_freertos" + ], + "flasher": "esptool", + "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", + "flasher_args": "-b 1500000" } ] } diff --git a/test/hil/pi4_esp32.json b/test/hil/pi4_esp32.json deleted file mode 100644 index c95dd2d4e..000000000 --- a/test/hil/pi4_esp32.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "boards": [ - { - "name": "espressif_s3_devkitm", - "uid": "84F703C084E4", - "tests": [ - "cdc_msc_freertos", "hid_composite_freertos" - ], - "flasher": "esptool", - "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", - "flasher_args": "-b 1500000" - } - ] -} diff --git a/tools/build.py b/tools/build.py index 884cd56f4..967f7c95e 100644 --- a/tools/build.py +++ b/tools/build.py @@ -1,8 +1,8 @@ +import argparse import os import sys import time import subprocess -import click from pathlib import Path from multiprocessing import Pool @@ -125,13 +125,20 @@ def build_family(family, toolchain, build_system): return ret -@click.command() -@click.argument('families', nargs=-1, required=False) -@click.option('-b', '--board', multiple=True, default=None, help='Boards to build') -@click.option('-t', '--toolchain', default='gcc', help='Toolchain to use, default is gcc') -@click.option('-s', '--build-system', default='cmake', help='Build system to use, default is cmake') -def main(families, board, toolchain, build_system): - if len(families) == 0 and len(board) == 0: +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('families', nargs='*', default=[], help='Families to build') + parser.add_argument('-b', '--board', action='append', default=[], help='Boards to build') + parser.add_argument('-t', '--toolchain', default='gcc', help='Toolchain to use, default is gcc') + parser.add_argument('-s', '--build-system', default='cmake', help='Build system to use, default is cmake') + args = parser.parse_args() + + families = args.families + boards = args.board + toolchain = args.toolchain + build_system = args.build_system + + if len(families) == 0 and len(boards) == 0: print("Please specify families or board to build") return 1 @@ -159,12 +166,23 @@ def main(families, board, toolchain, build_system): total_result[2] += fret[2] # build board (only cmake) - if board is not None: - for b in board: - r = build_board_cmake(b, toolchain) - total_result[0] += r[0] - total_result[1] += r[1] - total_result[2] += r[2] + if boards is not None: + for b in boards: + if build_system == 'cmake': + r = build_board_cmake(b, toolchain) + total_result[0] += r[0] + total_result[1] += r[1] + total_result[2] += r[2] + elif build_system == 'make': + all_examples = get_examples(find_family(b)) + with Pool(processes=os.cpu_count()) as pool: + pool_args = list((map(lambda e, bb=b, o=f"TOOLCHAIN={toolchain}": [e, bb, o], all_examples))) + r = pool.starmap(build_utils.build_example, pool_args) + # sum all element of same index (column sum) + rsum = list(map(sum, list(zip(*r)))) + total_result[0] += rsum[0] + total_result[1] += rsum[1] + total_result[2] += rsum[2] total_time = time.monotonic() - total_time print(build_separator) diff --git a/tools/build_esp32.py b/tools/build_esp32.py deleted file mode 100644 index 951467c23..000000000 --- a/tools/build_esp32.py +++ /dev/null @@ -1,106 +0,0 @@ -import os -import glob -import sys -import subprocess -import time - -import build_utils - -SUCCEEDED = "\033[32msucceeded\033[0m" -FAILED = "\033[31mfailed\033[0m" -SKIPPED = "\033[33mskipped\033[0m" - -success_count = 0 -fail_count = 0 -skip_count = 0 -exit_status = 0 - -total_time = time.monotonic() - -build_format = '| {:30} | {:30} | {:18} | {:7} | {:6} | {:6} |' -build_separator = '-' * 107 - -def filter_with_input(mylist): - if len(sys.argv) > 1: - input_args = list(set(mylist).intersection(sys.argv)) - if len(input_args) > 0: - mylist[:] = input_args - - -# Build all examples if not specified -all_examples = [entry.replace('examples/', '') for entry in glob.glob("examples/*/*_freertos")] -filter_with_input(all_examples) -all_examples.append('device/board_test') -all_examples.sort() - -# Build all boards if not specified -all_boards = [] -for entry in os.scandir("hw/bsp/espressif/boards"): - if entry.is_dir(): - all_boards.append(entry.name) -filter_with_input(all_boards) -all_boards.sort() - -def build_board(example, board): - global success_count, fail_count, skip_count, exit_status - start_time = time.monotonic() - - # Check if board is skipped - build_dir = f"cmake-build/cmake-build-{board}/{example}" - - # Generate and build - r = subprocess.run(f"cmake examples/{example} -B {build_dir} -G \"Ninja\" -DBOARD={board} -DMAX3421_HOST=1", - shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - if r.returncode == 0: - r = subprocess.run(f"cmake --build {build_dir}", shell=True, stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - build_duration = time.monotonic() - start_time - flash_size = "-" - sram_size = "-" - - if r.returncode == 0: - success = SUCCEEDED - success_count += 1 - #(flash_size, sram_size) = build_size(example, board) - else: - exit_status = r.returncode - success = FAILED - fail_count += 1 - - title = build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size) - if os.getenv('CI'): - # always print build output if in CI - print(f"::group::{title}") - print(r.stdout.decode("utf-8")) - print(f"::endgroup::") - else: - # print build output if failed - print(title) - if r.returncode != 0: - print(r.stdout.decode("utf-8")) - - -def build_size(example, board): - #elf_file = 'examples/device/{}/_build/{}/{}-firmware.elf'.format(example, board, board) - elf_file = 'examples/device/{}/_build/{}/*.elf'.format(example, board) - size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") - size_list = size_output.split('\n')[1].split('\t') - flash_size = int(size_list[0]) - sram_size = int(size_list[1]) + int(size_list[2]) - return (flash_size, sram_size) - - -print(build_separator) -print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) -print(build_separator) - -for example in all_examples: - for board in all_boards: - build_board(example, board) - -total_time = time.monotonic() - total_time -print(build_separator) -print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, total_time)) -print(build_separator) - -sys.exit(exit_status) diff --git a/tools/get_deps.py b/tools/get_deps.py index 2359b4bd0..20cbe64c7 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -245,11 +245,10 @@ def main(): args = parser.parse_args() families = args.families - board = args.board + boards = args.board - if len(families) == 0 and len(board) == 0: - print("Please specify family or board to fetch") - return + if len(families) == 0 and len(boards) == 0: + print("Warning: family and board are not specified, only fetching mandatory dependencies.") status = 0 deps = list(deps_mandatory.keys()) @@ -258,8 +257,8 @@ def main(): deps += deps_optional.keys() else: families = list(families) - if board is not None: - for b in board: + if boards is not None: + for b in boards: f = find_family(b) if f is not None: families.append(f) -- cgit v1.3.1 From 4cecb759c9cc5854a12380814bc49a8efddcea3c Mon Sep 17 00:00:00 2001 From: Rbb666 Date: Sat, 11 May 2024 16:47:15 +0800 Subject: [osal]add usb host script. --- lib/rt-thread/SConscript | 52 ++++++++++++++++----------- lib/rt-thread/tusb_config.h | 71 +++++++++++++++++++++++++++++++++++++ lib/rt-thread/tusb_rt_thread_port.c | 5 +++ 3 files changed, 108 insertions(+), 20 deletions(-) diff --git a/lib/rt-thread/SConscript b/lib/rt-thread/SConscript index 205e12958..482f6d7b2 100644 --- a/lib/rt-thread/SConscript +++ b/lib/rt-thread/SConscript @@ -5,32 +5,44 @@ cwd = GetCurrentDir() src = Split(""" ../../src/tusb.c ../../src/common/tusb_fifo.c -../../src/device/usbd.c -../../src/device/usbd_control.c ./tusb_rt_thread_port.c """) path = [cwd, cwd + "/../../src"] -# BSP -if GetDepend(["SOC_FAMILY_STM32"]): - src += ["../../src/portable/synopsys/dwc2/dcd_dwc2.c", - "../../src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c"] - -if GetDepend(["SOC_NRF52840"]): - src += ["../../src/portable/nordic/nrf5x/dcd_nrf5x.c"] - -if GetDepend(["SOC_FAMILY_RENESAS"]): - src += ["../../src/portable/renesas/rusb2/dcd_rusb2.c", - "../../src/portable/renesas/rusb2/rusb2_common.c"] - -# Device class -if GetDepend(["PKG_TINYUSB_DEVICE_CDC"]): - src += ["../../src/class/cdc/cdc_device.c"] +LOCAL_CFLAGS = '' -if GetDepend(["PKG_TINYUSB_DEVICE_MSC"]): - src += ["../../src/class/msc/msc_device.c", "port/msc_device_port.c"] +# for device stack +if GetDepend(["PKG_TINYUSB_DEVICE_ENABLE"]): + src += ["../../src/device/usbd.c", + "../../src/device/usbd_control.c"] + # BSP + if GetDepend(["SOC_FAMILY_STM32"]): + src += ["../../src/portable/synopsys/dwc2/dcd_dwc2.c", + "../../src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c"] + + if GetDepend(["SOC_NRF52840"]): + src += ["../../src/portable/nordic/nrf5x/dcd_nrf5x.c"] + + if GetDepend(["SOC_FAMILY_RENESAS"]): + src += ["../../src/portable/renesas/rusb2/dcd_rusb2.c", + "../../src/portable/renesas/rusb2/rusb2_common.c"] + + # Device class + if GetDepend(["PKG_TINYUSB_DEVICE_UVC"]): + src += ["../../src/class/video/video_device.c"] + if GetDepend(["PKG_TINYUSB_DEVICE_CDC"]): + src += ["../../src/class/cdc/cdc_device.c"] + if GetDepend(["PKG_TINYUSB_DEVICE_MSC"]): + src += ["../../src/class/msc/msc_device.c", "port/msc_device_port.c"] + +# for host stack +if GetDepend(["PKG_TINYUSB_HOST_ENABLE"]): + src += ["../../src/host/usbh.c", "../../src/host/hub.c"] + + if GetDepend(["SOC_FAMILY_RENESAS"]): + src += ["../../src/portable/renesas/rusb2/hcd_rusb2.c", + "../../src/portable/renesas/rusb2/rusb2_common.c"] -LOCAL_CFLAGS = '' if rtconfig.PLATFORM == 'gcc' or rtconfig.PLATFORM == 'armclang': # GCC or Keil AC6 LOCAL_CFLAGS += ' -std=c99' diff --git a/lib/rt-thread/tusb_config.h b/lib/rt-thread/tusb_config.h index 8b145f3f7..b3c3bf43f 100644 --- a/lib/rt-thread/tusb_config.h +++ b/lib/rt-thread/tusb_config.h @@ -113,6 +113,11 @@ extern "C" { //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- +#if defined(PKG_TINYUSB_DEVICE_ENABLE) + #define CFG_TUD_ENABLED (1) +#else + #define CFG_TUD_ENABLED (0) +#endif #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE PKG_TINYUSB_EDPT0_SIZE @@ -138,6 +143,72 @@ extern "C" { #define PKG_TINYUSB_DEVICE_HID_STRING "" #endif +//-------------------------------------------------------------------- +// HOST CONFIGURATION +//-------------------------------------------------------------------- +#if defined(PKG_TINYUSB_HOST_ENABLE) + #define CFG_TUH_ENABLED (1) +#else + #define CFG_TUH_ENABLED (0) +#endif + +#if (PKG_TINYUSB_HOST_PORT == 0) +#undef CFG_TUSB_RHPORT0_MODE +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | PKG_TINYUSB_HOST_PORT_SPEED) +#endif + +#if (PKG_TINYUSB_HOST_PORT == 1) +#undef CFG_TUSB_RHPORT1_MODE +#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_HOST | PKG_TINYUSB_HOST_PORT_SPEED) +#endif + +#define BOARD_TUH_RHPORT PKG_TINYUSB_HOST_PORT // FULL SPEED +#define BOARD_TUH_MAX_SPEED PKG_TINYUSB_HOST_PORT_SPEED +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED + +//------------------------- Board Specific -------------------------- + +// RHPort number used for host can be defined by board.mk, default to port 0 +#ifndef BOARD_TUH_RHPORT +#define BOARD_TUH_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUH_MAX_SPEED +#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +// Size of buffer to hold descriptors and other data used for enumeration +#define CFG_TUH_ENUMERATION_BUFSIZE 256 + +#define CFG_TUH_HUB 2 // number of supported hubs +#define CFG_TUH_CDC 0 // CDC ACM +#define CFG_TUH_CDC_FTDI 0 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API +#define CFG_TUH_CDC_CP210X 0 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API +#define CFG_TUH_CDC_CH34X 0 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API +#define CFG_TUH_HID 0 // typical keyboard + mouse device can have 3-4 HID interfaces +#define CFG_TUH_MSC 0 +//#define CFG_TUH_VENDOR 3 + +// max device support (excluding hub device): 1 hub typically has 4 ports +#define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1) + +//------------- HID -------------// +#define CFG_TUH_HID_EPIN_BUFSIZE 64 +#define CFG_TUH_HID_EPOUT_BUFSIZE 64 + +//------------- CDC -------------// + +// Set Line Control state on enumeration/mounted: +// DTR ( bit 0), RTS (bit 1) +#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03 + +// Set Line Coding on enumeration/mounted, value for cdc_line_coding_t +// bit rate = 115200, 1 stop bit, no parity, 8 bit data width +#define CFG_TUH_CDC_LINE_CODING_ON_ENUM { 115200, CDC_LINE_CODING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } + + #ifdef __cplusplus } diff --git a/lib/rt-thread/tusb_rt_thread_port.c b/lib/rt-thread/tusb_rt_thread_port.c index d33e3ac60..7e04d2453 100644 --- a/lib/rt-thread/tusb_rt_thread_port.c +++ b/lib/rt-thread/tusb_rt_thread_port.c @@ -44,7 +44,12 @@ static void tusb_thread_entry(void *parameter) (void) parameter; while (1) { +#if CFG_TUH_ENABLED + tuh_task(); +#endif +#if CFG_TUD_ENABLED tud_task(); +#endif } } -- cgit v1.3.1 From 9ce44db56f145d2efeec6b67d0786230c1a735c4 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 11 May 2024 12:32:47 +0200 Subject: Always send 4 bytes feedback despite 10.14 format (Apple wtf ?!) --- src/class/audio/audio_device.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 77645c412..5ee0a4007 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1231,7 +1231,20 @@ static inline bool audiod_fb_send(audiod_function_t *audio) audio->feedback.send_buf = audio->feedback.value; } - return usbd_edpt_xfer(audio->rhport, audio->ep_fb, (uint8_t *) &audio->feedback.send_buf, apply_correction ? 3 : 4); + // About feedback format on FS + // + // 3 variables: Format | packetSize | sendSize | Working OS: + // 16.16 4 4 Linux, Windows + // 16.16 4 3 Linux + // 16.16 3 4 Linux + // 16.16 3 3 Linux + // 10.14 4 4 Linux + // 10.14 4 3 Linux + // 10.14 3 4 Linux, OSX + // 10.14 3 3 Linux + // + // OSX requires wMaxPacketSize=3 while sending 4 bytes (Wth ?!), so we still send 4 bytes even of correction is applied + return usbd_edpt_xfer(audio->rhport, audio->ep_fb, (uint8_t *) &audio->feedback.send_buf, 4); } #endif -- cgit v1.3.1 From ad85c37c039f9ef9fe2bf7e1fbc011609bcd98a6 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 11 May 2024 12:51:18 +0200 Subject: Optimize SOF. --- src/class/audio/audio_device.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 719e71e12..a6139ee42 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2045,8 +2045,6 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT: case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2: audiod_set_fb_params_freq(audio, fb_param.sample_freq, fb_param.frequency.mclk_freq); - // Enable SOF interrupt - usbd_sof_enable(rhport, true); break; case AUDIO_FEEDBACK_METHOD_FIFO_COUNT: @@ -2084,16 +2082,19 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Disable SOF interrupt if no driver has any enabled feedback EP - bool disable = true; + bool enable_sof = false; for(uint8_t i=0; i < CFG_TUD_AUDIO; i++) { - if (_audiod_fct[i].ep_fb != 0) + if (_audiod_fct[i].ep_fb != 0 && + (_audiod_fct[i].feedback.compute_method == AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED || + _audiod_fct[i].feedback.compute_method == AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT || + _audiod_fct[i].feedback.compute_method == AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2 )) { - disable = false; + enable_sof = true; break; } } - if (disable) usbd_sof_enable(rhport, SOF_CONSUMER_AUDIO, false); + usbd_sof_enable(rhport, SOF_CONSUMER_AUDIO, enable_sof); #endif #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL -- cgit v1.3.1 From 256ccc47571b36dd8f5aaeaebe583cb7640a4b8d Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 11 May 2024 12:57:38 +0200 Subject: Fix CI. --- src/class/audio/audio_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index a6139ee42..0df24c163 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1243,7 +1243,7 @@ static inline bool audiod_fb_send(audiod_function_t *audio) // 10.14 3 4 Linux, OSX // 10.14 3 3 Linux // - // OSX requires wMaxPacketSize=3 while sending 4 bytes (Wth ?!), so we still send 4 bytes even of correction is applied + // OSX requires wMaxPacketSize=3 while sending 4 bytes (WTF ?!), so we still send 4 bytes even of correction is applied return usbd_edpt_xfer(audio->rhport, audio->ep_fb, (uint8_t *) &audio->feedback.send_buf, 4); } #endif -- cgit v1.3.1 From 08f9e4e0c8f95b28207603309974e6f15cfee87e Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 12 May 2024 13:57:17 +0200 Subject: Hint missing import, exit on error. --- examples/device/uac2_speaker_fb/src/audio_debug.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/examples/device/uac2_speaker_fb/src/audio_debug.py b/examples/device/uac2_speaker_fb/src/audio_debug.py index 182d6ca89..336c46c01 100644 --- a/examples/device/uac2_speaker_fb/src/audio_debug.py +++ b/examples/device/uac2_speaker_fb/src/audio_debug.py @@ -1,8 +1,13 @@ # Install python3 HID package https://pypi.org/project/hid/ -import hid +# Install python3 matplotlib package https://pypi.org/project/matplotlib/ + from ctypes import * -import matplotlib.pyplot as plt -import matplotlib.animation as animation +try: + import hid + import matplotlib.pyplot as plt + import matplotlib.animation as animation +except: + print("Missing import, please try 'pip install hid matplotlib' or consult your OS's python package manager.") # Example must be compiled with CFG_AUDIO_DEBUG=1 VID = 0xcafe @@ -32,15 +37,16 @@ if dev: def animate(i): info = None for i in range(30): - str_in = dev.read(64, 10) - if str_in: + try: + str_in = dev.read(64, 50) info = audio_debug_info_t.from_buffer_copy(str_in) global fifo_avg global fifo_cnt fifo_avg.append(info.fifo_count_avg) fifo_cnt.append(info.fifo_count) - + except: + exit(1) # Limit to 1000 items fifo_avg = fifo_avg[-1000:] fifo_cnt = fifo_cnt[-1000:] -- cgit v1.3.1 From df6740353fc0a736df4253558618c188138a43a8 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 12 May 2024 14:02:07 +0200 Subject: Optimize fifo level display. --- examples/device/uac2_speaker_fb/src/main.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/examples/device/uac2_speaker_fb/src/main.c b/examples/device/uac2_speaker_fb/src/main.c index 187ff2afe..6609fcedb 100644 --- a/examples/device/uac2_speaker_fb/src/main.c +++ b/examples/device/uac2_speaker_fb/src/main.c @@ -92,6 +92,8 @@ void audio_task(void); #if CFG_AUDIO_DEBUG void audio_debug_task(void); uint8_t current_alt_settings; +uint16_t fifo_count; +uint32_t fifo_count_avg; #endif /*------------- MAIN -------------*/ @@ -367,6 +369,21 @@ void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedba feedback_param->sample_freq = current_sample_rate; } +#if CFG_AUDIO_DEBUG +bool tud_audio_rx_done_pre_read_cb(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting) +{ + (void)rhport; + (void)func_id; + (void)ep_out; + (void)cur_alt_setting; + + fifo_count = tud_audio_available(); + // Same averaging method used in UAC2 class + fifo_count_avg = (uint32_t)(((uint64_t)fifo_count_avg * 63 + ((uint32_t)fifo_count << 16)) >> 6); + + return true; +} +#endif //--------------------------------------------------------------------+ // AUDIO Task //--------------------------------------------------------------------+ @@ -418,7 +435,6 @@ void led_blinking_task(void) //--------------------------------------------------------------------+ // HID interface for audio debug //--------------------------------------------------------------------+ - // Every 1ms, we will sent 1 debug information report void audio_debug_task(void) { @@ -427,12 +443,6 @@ void audio_debug_task(void) if ( start_ms == curr_ms ) return; // not enough time start_ms = curr_ms; - uint16_t fifo_count = tud_audio_available(); - static uint32_t fifo_count_avg; - - // Same averaging method used in UAC2 class - fifo_count_avg = (uint32_t)(((uint64_t)fifo_count_avg * 63 + ((uint32_t)fifo_count << 16)) >> 6); - audio_debug_info_t debug_info; debug_info.sample_rate = current_sample_rate; debug_info.alt_settings = current_alt_settings; -- cgit v1.3.1 From 32d0baaaf81df65ec386ac6940dbfa897348b086 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 12 May 2024 14:03:29 +0200 Subject: Tested 3 bytes feedback work on OSX. --- src/class/audio/audio_device.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 0df24c163..2a786725b 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1216,7 +1216,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP static inline bool audiod_fb_send(audiod_function_t *audio) { - bool apply_correction = TUSB_SPEED_FULL == tud_speed_get() && audio->feedback.format_correction; + bool apply_correction = (TUSB_SPEED_FULL == tud_speed_get()) && audio->feedback.format_correction; // Format the feedback value if (apply_correction) { @@ -1226,6 +1226,7 @@ static inline bool audiod_fb_send(audiod_function_t *audio) *(fb++) = (audio->feedback.value >> 2) & 0xFF; *(fb++) = (audio->feedback.value >> 10) & 0xFF; *(fb++) = (audio->feedback.value >> 18) & 0xFF; + *fb = 0; } else { audio->feedback.send_buf = audio->feedback.value; @@ -1241,10 +1242,10 @@ static inline bool audiod_fb_send(audiod_function_t *audio) // 10.14 4 4 Linux // 10.14 4 3 Linux // 10.14 3 4 Linux, OSX - // 10.14 3 3 Linux + // 10.14 3 3 Linux, OSX // - // OSX requires wMaxPacketSize=3 while sending 4 bytes (WTF ?!), so we still send 4 bytes even of correction is applied - return usbd_edpt_xfer(audio->rhport, audio->ep_fb, (uint8_t *) &audio->feedback.send_buf, 4); + // We send 3 bytes since sending packet larger than wMaxPacketSize is pretty ugly + return usbd_edpt_xfer(audio->rhport, audio->ep_fb, (uint8_t *) &audio->feedback.send_buf, apply_correction ? 3 : 4); } #endif -- cgit v1.3.1 From 301fb2a9f77a50c806c2147946eb434e360be8b0 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 12 May 2024 14:05:57 +0200 Subject: Fix CI. --- examples/device/uac2_speaker_fb/src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/device/uac2_speaker_fb/src/main.c b/examples/device/uac2_speaker_fb/src/main.c index 6609fcedb..6ac8fe989 100644 --- a/examples/device/uac2_speaker_fb/src/main.c +++ b/examples/device/uac2_speaker_fb/src/main.c @@ -373,6 +373,7 @@ void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedba bool tud_audio_rx_done_pre_read_cb(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting) { (void)rhport; + (void)n_bytes_received; (void)func_id; (void)ep_out; (void)cur_alt_setting; -- cgit v1.3.1 From d54a1578aadfce059550801ec78f715f249ccb76 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 12 May 2024 17:30:43 +0200 Subject: Typo. --- examples/device/uac2_speaker_fb/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/device/uac2_speaker_fb/src/main.c b/examples/device/uac2_speaker_fb/src/main.c index 6ac8fe989..8573dfa4c 100644 --- a/examples/device/uac2_speaker_fb/src/main.c +++ b/examples/device/uac2_speaker_fb/src/main.c @@ -370,7 +370,7 @@ void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedba } #if CFG_AUDIO_DEBUG -bool tud_audio_rx_done_pre_read_cb(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting) +bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting) { (void)rhport; (void)n_bytes_received; -- cgit v1.3.1 From 67456357c54ee81e8418a9e814df774b1a3dee85 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 12 May 2024 18:59:32 +0200 Subject: Fix HS playback on OSX. --- src/class/audio/audio_device.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 2a786725b..e82d52a5b 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2050,7 +2050,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * case AUDIO_FEEDBACK_METHOD_FIFO_COUNT: { - /* Initialize the threshold level to half filled */ + // Initialize the threshold level to half filled uint16_t fifo_lvl_thr; #if CFG_TUD_AUDIO_ENABLE_DECODING fifo_lvl_thr = tu_fifo_depth(&audio->rx_supp_ff[0]) / 2; @@ -2059,11 +2059,16 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #endif audio->feedback.compute.fifo_count.fifo_lvl_thr = fifo_lvl_thr; audio->feedback.compute.fifo_count.fifo_lvl_avg = ((uint32_t)fifo_lvl_thr) << 16; - /* Avoid 64bit division */ + // Avoid 64bit division uint32_t nominal = ((fb_param.sample_freq / 100) << 16) / (frame_div / 100); audio->feedback.compute.fifo_count.nom_value = nominal; audio->feedback.compute.fifo_count.rate_const[0] = (audio->feedback.max_value - nominal) / fifo_lvl_thr; audio->feedback.compute.fifo_count.rate_const[1] = (nominal - audio->feedback.min_value) / fifo_lvl_thr; + // On HS feedback is more sensitive since packet size can vary every MSOF, could cause instability + if(tud_speed_get() == TUSB_SPEED_HIGH) { + audio->feedback.compute.fifo_count.rate_const[0] /= 8; + audio->feedback.compute.fifo_count.rate_const[1] /= 8; + } } break; -- cgit v1.3.1 From 6f47746e5ff6e33b25e12742d62bcbf69f8a27a0 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Mon, 13 May 2024 16:41:11 +0700 Subject: more ci update (#2642) * Circi use small docker * caching espressif docker image * only run make job on pull request or push to master * hw test run on pull request only, rename build_cmake to build.yml * enable all ci build, cmake(clang) and make(*) only run with pull_request or push to master --- .circleci/config.yml | 2 + .github/actions/setup_toolchain/action.yml | 11 +- .../actions/setup_toolchain/download/action.yml | 19 +-- .../actions/setup_toolchain/espressif/action.yml | 42 +++++++ .github/workflows/build.yml | 136 +++++++++++++++++++++ .github/workflows/build_cmake.yml | 129 ------------------- .github/workflows/build_iar.yml | 9 -- .github/workflows/hil_test.yml | 10 -- tools/get_deps.py | 13 +- 9 files changed, 209 insertions(+), 162 deletions(-) create mode 100644 .github/actions/setup_toolchain/espressif/action.yml create mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/build_cmake.yml diff --git a/.circleci/config.yml b/.circleci/config.yml index d5d401c51..d91de8419 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -13,6 +13,8 @@ jobs: # See: https://circleci.com/developer/images/image/cimg/base - image: cimg/base:current + resource_class: small + # Add steps to the job # See: https://circleci.com/docs/jobs-steps/#steps-overview & https://circleci.com/docs/configuration-reference/#steps steps: diff --git a/.github/actions/setup_toolchain/action.yml b/.github/actions/setup_toolchain/action.yml index e6c79e7dd..34bcbc68b 100644 --- a/.github/actions/setup_toolchain/action.yml +++ b/.github/actions/setup_toolchain/action.yml @@ -2,11 +2,11 @@ name: Setup Toolchain inputs: toolchain: + description: 'Toolchain name' required: true - type: string toolchain_url: + description: 'Toolchain URL or version' required: false - type: string outputs: build_option: @@ -24,8 +24,10 @@ runs: - name: Pull ESP-IDF docker if: inputs.toolchain == 'esp-idf' - run: docker pull espressif/idf:${{ inputs.toolchain_url }} - shell: bash + uses: ./.github/actions/setup_toolchain/espressif + with: + toolchain: ${{ inputs.toolchain }} + toolchain_url: ${{ inputs.toolchain_url }} - name: Download Toolchain if: >- @@ -33,6 +35,7 @@ runs: inputs.toolchain != 'esp-idf' uses: ./.github/actions/setup_toolchain/download with: + toolchain: ${{ inputs.toolchain }} toolchain_url: ${{ inputs.toolchain_url }} - name: Set toolchain option diff --git a/.github/actions/setup_toolchain/download/action.yml b/.github/actions/setup_toolchain/download/action.yml index db85e9027..0b35bddb1 100644 --- a/.github/actions/setup_toolchain/download/action.yml +++ b/.github/actions/setup_toolchain/download/action.yml @@ -1,29 +1,32 @@ name: Download Toolchain inputs: + toolchain: + description: 'Toolchain name' + required: true toolchain_url: + description: 'Toolchain URL' required: true - type: string runs: using: "composite" steps: - name: Cache Toolchain uses: actions/cache@v4 - id: cache-toolchain + id: cache-toolchain-download with: - path: ~/cache/toolchain - key: ${{ runner.os }}-${{ inputs.toolchain_url }} + path: ~/cache/${{ inputs.toolchain }} + key: ${{ runner.os }}-${{ inputs.toolchain }}-${{ inputs.toolchain_url }} - name: Install Toolchain - if: steps.cache-toolchain.outputs.cache-hit != 'true' + if: steps.cache-toolchain-download.outputs.cache-hit != 'true' run: | - mkdir -p ~/cache/toolchain + mkdir -p ~/cache/${{ inputs.toolchain }} wget --progress=dot:mega ${{ inputs.toolchain_url }} -O toolchain.tar.gz - tar -C ~/cache/toolchain -xaf toolchain.tar.gz + tar -C ~/cache/${{ inputs.toolchain }} -xaf toolchain.tar.gz shell: bash - name: Set Toolchain Path run: | - echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` + echo >> $GITHUB_PATH `echo ~/cache/${{ inputs.toolchain }}/*/bin` shell: bash diff --git a/.github/actions/setup_toolchain/espressif/action.yml b/.github/actions/setup_toolchain/espressif/action.yml new file mode 100644 index 000000000..a4c6127c6 --- /dev/null +++ b/.github/actions/setup_toolchain/espressif/action.yml @@ -0,0 +1,42 @@ +name: Setup ESP-IDF Toolchain + +inputs: + toolchain: + description: 'Toolchain name' + required: true + toolchain_url: + description: 'Toolchain URL or version' + required: true + +runs: + using: "composite" + steps: + - id: set-docker-image + run: | + DOCKER_IMAGE=$HOME/cache/${{ inputs.toolchain }}/docker_image.tar + echo "DOCKER_IMAGE=$DOCKER_IMAGE" >> $GITHUB_ENV + echo "DOCKER_IMAGE=$DOCKER_IMAGE" >> $GITHUB_OUTPUT + shell: bash + + - name: Cache Docker Image + uses: actions/cache@v4 + id: cache-toolchain-espressif + with: + path: ${{ steps.set-docker-image.outputs.DOCKER_IMAGE }} + key: ${{ runner.os }}-${{ inputs.toolchain }}-${{ inputs.toolchain_url }} + + - name: Pull and Save Docker Image + if: steps.cache-toolchain-espressif.outputs.cache-hit != 'true' + run: | + docker pull espressif/idf:${{ inputs.toolchain_url }} + mkdir -p ~/cache/${{ inputs.toolchain }} + docker save -o $DOCKER_IMAGE espressif/idf:${{ inputs.toolchain_url }} + du -sh $DOCKER_IMAGE + shell: bash + + - name: Load Docker Image + if: steps.cache-toolchain-espressif.outputs.cache-hit == 'true' + run: | + du -sh $DOCKER_IMAGE + docker load --input $DOCKER_IMAGE + shell: bash diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..d51e1c92a --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,136 @@ +name: Build + +on: + workflow_dispatch: + push: + paths: + - 'src/**' + - 'examples/**' + - 'lib/**' + - 'hw/**' + - 'tools/get_deps.py' + - 'tools/build.py' + - '.github/actions/**' + - '.github/workflows/build.yml' + - '.github/workflows/build_util.yml' + - '.github/workflows/ci_set_matrix.py' + pull_request: + branches: [ master ] + paths: + - 'src/**' + - 'examples/**' + - 'lib/**' + - 'hw/**' + - 'tools/get_deps.py' + - 'tools/build.py' + - '.github/actions/**' + - '.github/workflows/build.yml' + - '.github/workflows/build_util.yml' + - '.github/workflows/ci_set_matrix.py' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + set-matrix: + runs-on: ubuntu-latest + outputs: + json: ${{ steps.set-matrix-json.outputs.matrix }} + steps: + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Generate matrix json + id: set-matrix-json + run: | + MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py) + echo "matrix=$MATRIX_JSON" + echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT + + # --------------------------------------- + # Build CMake + # --------------------------------------- + cmake: + needs: set-matrix + uses: ./.github/workflows/build_util.yml + strategy: + fail-fast: false + matrix: + toolchain: + - 'aarch64-gcc' + - 'arm-clang' + - 'arm-gcc' + - 'msp430-gcc' + - 'riscv-gcc' + if: >- + matrix.toolchain != 'arm-clang' || + github.event_name == 'pull_request' || + (github.event_name == 'push' && github.ref == 'refs/heads/master') + with: + build-system: 'cmake' + toolchain: ${{ matrix.toolchain }} + toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} + build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} + + # --------------------------------------- + # Build Make + # --------------------------------------- + make: + if: >- + github.event_name == 'pull_request' || + (github.event_name == 'push' && github.ref == 'refs/heads/master') + needs: set-matrix + uses: ./.github/workflows/build_util.yml + strategy: + fail-fast: false + matrix: + toolchain: + - 'aarch64-gcc' + #- 'arm-clang' + - 'arm-gcc' + - 'msp430-gcc' + - 'riscv-gcc' + with: + build-system: 'make' + toolchain: ${{ matrix.toolchain }} + toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} + build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} + + # --------------------------------------- + # Build Make on Windows/MacOS + # --------------------------------------- + make-os: + uses: ./.github/workflows/build_util.yml + strategy: + fail-fast: false + matrix: + os: [windows-latest, macos-latest] + with: + os: ${{ matrix.os }} + build-system: 'make' + toolchain: 'arm-gcc' + build-args: '["-bstm32f411disco"]' + + # --------------------------------------- + # Build Espressif + # --------------------------------------- + espressif: + uses: ./.github/workflows/build_util.yml + strategy: + fail-fast: false + matrix: + board: + # ESP32-S2 + - 'espressif_kaluga_1' + # ESP32-S3 skip since devkitm is also compiled in hil-test workflow + #- 'espressif_s3_devkitm' + with: + build-system: 'cmake' + toolchain: 'esp-idf' + toolchain_url: 'v5.1.1' + build-args: '["-b${{ matrix.board }}"]' diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml deleted file mode 100644 index 4723cf8d9..000000000 --- a/.github/workflows/build_cmake.yml +++ /dev/null @@ -1,129 +0,0 @@ -name: Build - -on: - workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'tools/get_deps.py' - - 'tools/build.py' - - '.github/actions/**' - - '.github/workflows/build_cmake.yml' - - '.github/workflows/build_util.yml' - - '.github/workflows/ci_set_matrix.py' - pull_request: - branches: [ master ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'tools/get_deps.py' - - 'tools/build.py' - - '.github/actions/**' - - '.github/workflows/build_cmake.yml' - - '.github/workflows/build_util.yml' - - '.github/workflows/ci_set_matrix.py' -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - set-matrix: - runs-on: ubuntu-latest - outputs: - json: ${{ steps.set-matrix-json.outputs.matrix }} - steps: - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Generate matrix json - id: set-matrix-json - run: | - MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py) - echo "matrix=$MATRIX_JSON" - echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT - - # --------------------------------------- - # Build CMake - # --------------------------------------- - cmake: - needs: set-matrix - uses: ./.github/workflows/build_util.yml - strategy: - fail-fast: false - matrix: - toolchain: - - 'aarch64-gcc' - - 'arm-clang' - - 'arm-gcc' - - 'msp430-gcc' - - 'riscv-gcc' - with: - build-system: 'cmake' - toolchain: ${{ matrix.toolchain }} - toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} - build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} - - # --------------------------------------- - # Build Make - # --------------------------------------- - make: - needs: set-matrix - uses: ./.github/workflows/build_util.yml - strategy: - fail-fast: false - matrix: - toolchain: - - 'aarch64-gcc' - #- 'arm-clang' - - 'arm-gcc' - - 'msp430-gcc' - - 'riscv-gcc' - with: - build-system: 'make' - toolchain: ${{ matrix.toolchain }} - toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} - build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} - - # --------------------------------------- - # Build Make on Windows/MacOS - # --------------------------------------- - make-os: - uses: ./.github/workflows/build_util.yml - strategy: - fail-fast: false - matrix: - os: [windows-latest, macos-latest] - with: - os: ${{ matrix.os }} - build-system: 'make' - toolchain: 'arm-gcc' - build-args: '["-bstm32f411disco"]' - - # --------------------------------------- - # Build Espressif - # --------------------------------------- - espressif: - uses: ./.github/workflows/build_util.yml - strategy: - fail-fast: false - matrix: - board: - # ESP32-S2 - - 'espressif_kaluga_1' - # ESP32-S3 skip since devkitm is also compiled in hil-test workflow - #- 'espressif_s3_devkitm' - with: - build-system: 'cmake' - toolchain: 'esp-idf' - toolchain_url: 'v5.1.1' - build-args: '["-b${{ matrix.board }}"]' diff --git a/.github/workflows/build_iar.yml b/.github/workflows/build_iar.yml index 34dbda192..c8a095c18 100644 --- a/.github/workflows/build_iar.yml +++ b/.github/workflows/build_iar.yml @@ -2,15 +2,6 @@ name: Build IAR on: workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'tools/get_deps.py' - - 'test/hil/**' - - '.github/workflows/build_iar.yml' pull_request: branches: [ master ] paths: diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index 796ff32dc..eb3f2cbab 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -2,16 +2,6 @@ name: Hardware Test on: workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'test/hil/**' - - 'tools/get_deps.py' - - '.github/actions/**' - - '.github/workflows/hil_test.yml' pull_request: branches: [ master ] paths: diff --git a/tools/get_deps.py b/tools/get_deps.py index 20cbe64c7..2c2f97b4b 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -242,10 +242,12 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument('families', nargs='*', default=[], help='Families to fetch') parser.add_argument('-b', '--board', action='append', default=[], help='Boards to fetch') + parser.add_argument('--print', action='store_true', help='Print commit hash only') args = parser.parse_args() families = args.families boards = args.board + print_only = args.print if len(families) == 0 and len(boards) == 0: print("Warning: family and board are not specified, only fetching mandatory dependencies.") @@ -268,8 +270,15 @@ def main(): if f in deps_optional[d][2]: deps.append(d) - with Pool() as pool: - status = sum(pool.map(get_a_dep, deps)) + if print_only: + pvalue = {} + for d in deps: + commit = deps_all[d][1] + pvalue[d] = commit + print(pvalue) + else: + with Pool() as pool: + status = sum(pool.map(get_a_dep, deps)) return status -- cgit v1.3.1 From 7cf1bdd2848d6c36e9659acaf77c83a1fa99d04f Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Mon, 13 May 2024 20:27:49 +0700 Subject: Ci tweak3 (#2643) - enable --one-per-family to build 1 board per family, also skip family if board specified in -b also present - minimize ci run for push event - only build one board per family - skip hil test on both pi4 and hfp - full build will be runn for PR event - IAR always build 1 board per family regardless of event - update build.py to optimize make - remove all setup python since we don't really need it --- .github/actions/setup_toolchain/action.yml | 3 + .github/workflows/build.yml | 50 +++++++--- .github/workflows/build_iar.yml | 50 ---------- .github/workflows/build_renesas.yml | 5 - .github/workflows/build_util.yml | 21 +++-- .github/workflows/ci_set_matrix.py | 22 +++-- .github/workflows/hil_test.yml | 12 +-- .github/workflows/pre-commit.yml | 5 - hw/bsp/stm32f0/family.c | 2 +- hw/bsp/stm32f1/family.c | 2 +- hw/bsp/stm32f2/family.c | 3 +- hw/bsp/stm32f3/family.c | 5 +- hw/bsp/stm32u5/family.c | 3 +- hw/bsp/stm32wb/family.c | 5 +- tools/build.py | 142 +++++++++++++++++------------ 15 files changed, 166 insertions(+), 164 deletions(-) delete mode 100644 .github/workflows/build_iar.yml diff --git a/.github/actions/setup_toolchain/action.yml b/.github/actions/setup_toolchain/action.yml index 34bcbc68b..19fe28b0c 100644 --- a/.github/actions/setup_toolchain/action.yml +++ b/.github/actions/setup_toolchain/action.yml @@ -32,6 +32,7 @@ runs: - name: Download Toolchain if: >- inputs.toolchain != 'arm-gcc' && + inputs.toolchain != 'arm-iar' && inputs.toolchain != 'esp-idf' uses: ./.github/actions/setup_toolchain/download with: @@ -44,6 +45,8 @@ runs: BUILD_OPTION="" if [[ "${{ inputs.toolchain }}" == *"clang"* ]]; then BUILD_OPTION="--toolchain clang" + elif [[ "${{ inputs.toolchain }}" == "arm-iar" ]]; then + BUILD_OPTION="--toolchain iar" fi echo "build_option=$BUILD_OPTION" echo "build_option=$BUILD_OPTION" >> $GITHUB_OUTPUT diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d51e1c92a..2cd348847 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,11 +37,6 @@ jobs: outputs: json: ${{ steps.set-matrix-json.outputs.matrix }} steps: - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - name: Checkout TinyUSB uses: actions/checkout@v4 @@ -63,27 +58,22 @@ jobs: matrix: toolchain: - 'aarch64-gcc' - - 'arm-clang' +# - 'arm-clang' - 'arm-gcc' - 'msp430-gcc' - 'riscv-gcc' - if: >- - matrix.toolchain != 'arm-clang' || - github.event_name == 'pull_request' || - (github.event_name == 'push' && github.ref == 'refs/heads/master') with: build-system: 'cmake' toolchain: ${{ matrix.toolchain }} toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} + one-per-family: ${{ github.event_name != 'pull_request' }} # --------------------------------------- # Build Make # --------------------------------------- make: - if: >- - github.event_name == 'pull_request' || - (github.event_name == 'push' && github.ref == 'refs/heads/master') + #if: github.event_name == 'pull_request' needs: set-matrix uses: ./.github/workflows/build_util.yml strategy: @@ -100,6 +90,7 @@ jobs: toolchain: ${{ matrix.toolchain }} toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} + one-per-family: ${{ github.event_name != 'pull_request' }} # --------------------------------------- # Build Make on Windows/MacOS @@ -114,7 +105,8 @@ jobs: os: ${{ matrix.os }} build-system: 'make' toolchain: 'arm-gcc' - build-args: '["-bstm32f411disco"]' + build-args: '["stm32h7"]' + one-per-family: true # --------------------------------------- # Build Espressif @@ -134,3 +126,33 @@ jobs: toolchain: 'esp-idf' toolchain_url: 'v5.1.1' build-args: '["-b${{ matrix.board }}"]' + + # --------------------------------------- + # Build IAR on HFP self-hosted + # --------------------------------------- + arm-iar: + if: github.repository_owner == 'hathach' + needs: set-matrix + runs-on: [self-hosted, Linux, X64, hifiphile] + env: + BUILD_ARGS: ${{ join(fromJSON(needs.set-matrix.outputs.json)['arm-iar'].family, ' ') }} + steps: + - name: Clean workspace + run: | + echo "Cleaning up previous run" + rm -rf "${{ github.workspace }}" + mkdir -p "${{ github.workspace }}" + + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Get Dependencies + run: python3 tools/get_deps.py $BUILD_ARGS + + - name: Build + run: python3 tools/build.py --one-per-family --toolchain iar $BUILD_ARGS + + - name: Test on actual hardware (hardware in the loop) + if: github.event_name == 'pull_request' + run: | + python3 test/hil/hil_test.py hfp.json diff --git a/.github/workflows/build_iar.yml b/.github/workflows/build_iar.yml deleted file mode 100644 index c8a095c18..000000000 --- a/.github/workflows/build_iar.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: Build IAR - -on: - workflow_dispatch: - pull_request: - branches: [ master ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'tools/get_deps.py' - - 'test/hil/**' - - '.github/workflows/build_iar.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - cmake: - if: github.repository_owner == 'hathach' - runs-on: [self-hosted, Linux, X64, hifiphile] - strategy: - fail-fast: false - matrix: - family: - # Alphabetical order - # Note: bundle multiple families into a matrix since there is only one self-hosted instance can - # run IAR build. Too many matrix can hurt due to setup/teardown overhead. - - 'lpc43 stm32f0 stm32f1 stm32f7 stm32g0 stm32g4 stm32l4' - steps: - - name: Clean workspace - run: | - echo "Cleaning up previous run" - rm -rf "${{ github.workspace }}" - mkdir -p "${{ github.workspace }}" - - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Get Dependencies - run: python3 tools/get_deps.py ${{ matrix.family }} - - - name: Build - run: python3 tools/build.py --toolchain iar ${{ matrix.family }} - - - name: Test on actual hardware (hardware in the loop) - run: | - python3 test/hil/hil_test.py hfp.json diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml index 1be49344f..3d2cbab28 100644 --- a/.github/workflows/build_renesas.yml +++ b/.github/workflows/build_renesas.yml @@ -34,11 +34,6 @@ jobs: # Alphabetical order - 'rx' steps: - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - name: Checkout TinyUSB uses: actions/checkout@v4 diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index f8ad1900c..49a9feabd 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -15,6 +15,10 @@ on: build-args: required: true type: string + one-per-family: + required: false + default: false + type: boolean os: required: false type: string @@ -31,11 +35,6 @@ jobs: - name: Checkout TinyUSB uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - name: Setup Toolchain id: setup-toolchain uses: ./.github/actions/setup_toolchain @@ -48,10 +47,20 @@ jobs: with: arg: ${{ matrix.arg }} + - name: Set build one-per-family option + id: set-one-per-family + run: | + if [[ "${{ inputs.one-per-family }}" == "true" ]]; then + BUILD_OPTION="--one-per-family" + fi + echo "build_option=$BUILD_OPTION" + echo "build_option=$BUILD_OPTION" >> $GITHUB_OUTPUT + shell: bash + - name: Build if: inputs.toolchain != 'esp-idf' run: | - python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ matrix.arg }} + python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} - name: Build using ESP-IDF docker if: inputs.toolchain == 'esp-idf' diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index ea758d917..62239c9ad 100644 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -4,6 +4,7 @@ import json toolchain_list = { "aarch64-gcc": "https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz", "arm-clang": "https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-17.0.1/LLVMEmbeddedToolchainForArm-17.0.1-Linux-x86_64.tar.xz", + "arm-iar": "", "arm-gcc": "", "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v10.1.0-1.1/xpack-riscv-none-embed-gcc-10.1.0-1.1-linux-x64.tar.gz", @@ -28,12 +29,12 @@ family_list = { "rp2040": ["arm-gcc"], "samd11 samd21 saml2x": ["arm-gcc", "arm-clang"], "samd5x_e5x samg": ["arm-gcc", "arm-clang"], - "stm32f0 stm32f1 stm32f2 stm32f3": ["arm-gcc", "arm-clang"], - "stm32f4": ["arm-gcc", "arm-clang"], - "stm32f7": ["arm-gcc", "arm-clang"], - "stm32g0 stm32g4 stm32h5": ["arm-gcc", "arm-clang"], - "stm32h7": ["arm-gcc", "arm-clang"], - "stm32l4 stm32u5 stm32wb": ["arm-gcc", "arm-clang"], + "stm32f0 stm32f1 stm32f2 stm32f3": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32f4": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32f7": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32g0 stm32g4 stm32h5": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32h7": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32l4 stm32u5 stm32wb": ["arm-gcc", "arm-clang", "arm-iar"], "xmc4000": ["arm-gcc"], } @@ -43,7 +44,16 @@ def set_matrix_json(): for toolchain in toolchain_list.keys(): filtered_families = [family for family, supported_toolchain in family_list.items() if toolchain in supported_toolchain] + + # always add board in hfp.json for arm-iar + if toolchain == 'arm-iar': + with open('test/hil/hfp.json') as f: + hfp_data = json.load(f) + hfp_boards = [f"-b{board['name']}" for board in hfp_data['boards']] + filtered_families = filtered_families + hfp_boards + matrix[toolchain] = {"family": filtered_families, "toolchain_url": toolchain_list[toolchain]} + print(json.dumps(matrix)) diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index eb3f2cbab..adb5bf00e 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -30,11 +30,6 @@ jobs: - name: Checkout TinyUSB uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - name: Parse HIL json id: parse_hil_json run: | @@ -78,11 +73,6 @@ jobs: - name: Checkout TinyUSB uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - name: Parse HIL json id: parse_hil_json run: | @@ -131,7 +121,7 @@ jobs: - build-esp runs-on: [self-hosted, rp2040, nrf52840, esp32s3, hardware-in-the-loop] env: - BOARDS_LIST: "${{ needs.build.outputs.BOARDS_LIST }} ${{ needs.build-esp.outputs.BOARDS_LIST }}" + BOARDS_LIST: "${{ needs.build.outputs.BOARDS_LIST }} ${{ needs.build-esp.outputs.BOARDS_LIST }}" steps: - name: Clean workspace run: | diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index d1ffe6ca1..379a22ee2 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -14,11 +14,6 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - name: Setup Ruby uses: ruby/setup-ruby@v1 with: diff --git a/hw/bsp/stm32f0/family.c b/hw/bsp/stm32f0/family.c index 7ef126ae6..3079a1ed3 100644 --- a/hw/bsp/stm32f0/family.c +++ b/hw/bsp/stm32f0/family.c @@ -115,7 +115,7 @@ void board_init(void) { //--------------------------------------------------------------------+ void board_led_write(bool state) { - GPIO_PinState pin_state = (GPIO_PinState)(state ? LED_STATE_ON : (1 - LED_STATE_ON)); + GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } diff --git a/hw/bsp/stm32f1/family.c b/hw/bsp/stm32f1/family.c index 0c1b362ab..70f81e7fc 100644 --- a/hw/bsp/stm32f1/family.c +++ b/hw/bsp/stm32f1/family.c @@ -124,7 +124,7 @@ void board_init(void) { //--------------------------------------------------------------------+ void board_led_write(bool state) { - GPIO_PinState pin_state = (GPIO_PinState)(state ? LED_STATE_ON : (1 - LED_STATE_ON)); + GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } diff --git a/hw/bsp/stm32f2/family.c b/hw/bsp/stm32f2/family.c index 8b1c56423..62cca327b 100644 --- a/hw/bsp/stm32f2/family.c +++ b/hw/bsp/stm32f2/family.c @@ -108,7 +108,8 @@ void board_init(void) { //--------------------------------------------------------------------+ void board_led_write(bool state) { - HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); + GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON)); + HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { diff --git a/hw/bsp/stm32f3/family.c b/hw/bsp/stm32f3/family.c index 7c194a694..e7488ba84 100644 --- a/hw/bsp/stm32f3/family.c +++ b/hw/bsp/stm32f3/family.c @@ -108,7 +108,8 @@ void board_init(void) { //--------------------------------------------------------------------+ void board_led_write(bool state) { - HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); + GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON)); + HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { @@ -142,7 +143,7 @@ uint32_t board_millis(void) { #endif void HardFault_Handler(void) { - asm("bkpt"); + asm("bkpt 0"); } // Required by __libc_init_array in startup code if we are compiling using diff --git a/hw/bsp/stm32u5/family.c b/hw/bsp/stm32u5/family.c index ec64f7622..d779b5c96 100644 --- a/hw/bsp/stm32u5/family.c +++ b/hw/bsp/stm32u5/family.c @@ -203,7 +203,8 @@ void board_init(void) { //--------------------------------------------------------------------+ void board_led_write(bool state) { - HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); + GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON)); + HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { diff --git a/hw/bsp/stm32wb/family.c b/hw/bsp/stm32wb/family.c index 1dc789407..6051388a7 100644 --- a/hw/bsp/stm32wb/family.c +++ b/hw/bsp/stm32wb/family.c @@ -136,7 +136,8 @@ void board_init(void) { //--------------------------------------------------------------------+ void board_led_write(bool state) { - HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); + GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON)); + HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { @@ -174,7 +175,7 @@ uint32_t board_millis(void) { #endif void HardFault_Handler(void) { - asm("bkpt"); + asm("bkpt 1"); } // Required by __libc_init_array in startup code if we are compiling using diff --git a/tools/build.py b/tools/build.py index 967f7c95e..b937a7342 100644 --- a/tools/build.py +++ b/tools/build.py @@ -1,4 +1,5 @@ import argparse +import random import os import sys import time @@ -96,32 +97,61 @@ def build_board_cmake(board, toolchain): return ret -def build_family(family, toolchain, build_system): +def build_board_make_all_examples(board, toolchain, all_examples): + start_time = time.monotonic() + ret = [0, 0, 0] + + with Pool(processes=os.cpu_count()) as pool: + pool_args = list((map(lambda e, b=board, o=f"TOOLCHAIN={toolchain}": [e, b, o], all_examples))) + r = pool.starmap(build_utils.build_example, pool_args) + # sum all element of same index (column sum) + rsum = list(map(sum, list(zip(*r)))) + ret[0] += rsum[0] + ret[1] += rsum[1] + ret[2] += rsum[2] + duration = time.monotonic() - start_time + if ret[1] == 0: + status = SUCCEEDED + else: + status = FAILED + + flash_size = "-" + sram_size = "-" + example = 'all' + title = build_utils.build_format.format(example, board, status, "{:.2f}s".format(duration), flash_size, sram_size) + print(title) + return ret + + +def build_family(family, toolchain, build_system, one_per_family, boards): all_boards = [] for entry in os.scandir(f"hw/bsp/{family}/boards"): if entry.is_dir() and entry.name != 'pico_sdk': all_boards.append(entry.name) all_boards.sort() - # success, failed, skipped ret = [0, 0, 0] - if build_system == 'cmake': - for board in all_boards: - if build_board_cmake(board, toolchain): - ret[0] += 1 - else: - ret[1] += 1 - elif build_system == 'make': - all_examples = get_examples(family) - for example in all_examples: - with Pool(processes=os.cpu_count()) as pool: - pool_args = list((map(lambda b, e=example, o=f"TOOLCHAIN={toolchain}": [e, b, o], all_boards))) - r = pool.starmap(build_utils.build_example, pool_args) - # sum all element of same index (column sum) - rsum = list(map(sum, list(zip(*r)))) - ret[0] += rsum[0] - ret[1] += rsum[1] - ret[2] += rsum[2] + + # If only-one flag is set, select one random board + if one_per_family: + for b in boards: + # skip if -b already specify one in this family + if find_family(b) == family: + return ret + all_boards = [random.choice(all_boards)] + + # success, failed, skipped + all_examples = get_examples(family) + for board in all_boards: + r = [0, 0, 0] + if build_system == 'cmake': + r = build_board_cmake(board, toolchain) + elif build_system == 'make': + r = build_board_make_all_examples(board, toolchain, all_examples) + ret[0] += r[0] + ret[1] += r[1] + ret[2] += r[2] + return ret @@ -131,12 +161,14 @@ def main(): parser.add_argument('-b', '--board', action='append', default=[], help='Boards to build') parser.add_argument('-t', '--toolchain', default='gcc', help='Toolchain to use, default is gcc') parser.add_argument('-s', '--build-system', default='cmake', help='Build system to use, default is cmake') + parser.add_argument('-1', '--one-per-family', action='store_true', default=False, help='Build only one random board inside a family') args = parser.parse_args() families = args.families boards = args.board toolchain = args.toolchain build_system = args.build_system + one_per_family = args.one_per_family if len(families) == 0 and len(boards) == 0: print("Please specify families or board to build") @@ -145,50 +177,42 @@ def main(): print(build_separator) print(build_utils.build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) total_time = time.monotonic() - total_result = [0, 0, 0] - - # build families: cmake, make - if families is not None: - all_families = [] - if 'all' in families: - for entry in os.scandir("hw/bsp"): - if entry.is_dir() and entry.name != 'espressif' and os.path.isfile(entry.path + "/family.cmake"): - all_families.append(entry.name) - else: - all_families = list(families) - all_families.sort() - - # succeeded, failed - for f in all_families: - fret = build_family(f, toolchain, build_system) - total_result[0] += fret[0] - total_result[1] += fret[1] - total_result[2] += fret[2] - - # build board (only cmake) - if boards is not None: - for b in boards: - if build_system == 'cmake': - r = build_board_cmake(b, toolchain) - total_result[0] += r[0] - total_result[1] += r[1] - total_result[2] += r[2] - elif build_system == 'make': - all_examples = get_examples(find_family(b)) - with Pool(processes=os.cpu_count()) as pool: - pool_args = list((map(lambda e, bb=b, o=f"TOOLCHAIN={toolchain}": [e, bb, o], all_examples))) - r = pool.starmap(build_utils.build_example, pool_args) - # sum all element of same index (column sum) - rsum = list(map(sum, list(zip(*r)))) - total_result[0] += rsum[0] - total_result[1] += rsum[1] - total_result[2] += rsum[2] + result = [0, 0, 0] + + # build families + all_families = [] + if 'all' in families: + for entry in os.scandir("hw/bsp"): + if entry.is_dir() and entry.name != 'espressif' and os.path.isfile(entry.path + "/family.cmake"): + all_families.append(entry.name) + else: + all_families = list(families) + all_families.sort() + + # succeeded, failed + for f in all_families: + fret = build_family(f, toolchain, build_system, one_per_family, boards) + result[0] += fret[0] + result[1] += fret[1] + result[2] += fret[2] + + # build boards + for b in boards: + r = [0, 0, 0] + if build_system == 'cmake': + r = build_board_cmake(b, toolchain) + elif build_system == 'make': + all_examples = get_examples(find_family(b)) + r = build_board_make_all_examples(b, toolchain, all_examples) + result[0] += r[0] + result[1] += r[1] + result[2] += r[2] total_time = time.monotonic() - total_time print(build_separator) - print(f"Build Summary: {total_result[0]} {SUCCEEDED}, {total_result[1]} {FAILED} and took {total_time:.2f}s") + print(f"Build Summary: {result[0]} {SUCCEEDED}, {result[1]} {FAILED} and took {total_time:.2f}s") print(build_separator) - return total_result[1] + return result[1] if __name__ == '__main__': -- cgit v1.3.1 From 9d561410e58ba9efb6ef2bff7b03a2f47dee8d64 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Mon, 13 May 2024 18:57:03 +0200 Subject: revert (unverified) second race condition --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 805eb1dda..bb07063d2 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -77,18 +77,6 @@ #endif #endif -/** disable interrupts */ -#define DISABLE_IRQ() \ - uint32_t prim = __get_PRIMASK(); \ - __disable_irq(); - -/** (re)enable interrupts */ -#define ENABLE_IRQ() \ - if (!prim) \ - { \ - __enable_irq(); \ - } - /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ @@ -446,15 +434,11 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE)); if (control_status) { - DISABLE_IRQ(); - // Status Phase also requires EasyDMA has to be available as well !!!! edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS); // The nRF doesn't interrupt on status transmit so we queue up a success response. dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, is_in_isr()); - - ENABLE_IRQ(); } else if (dir == TUSB_DIR_OUT) { xfer->started = true; if (epnum == 0) { -- cgit v1.3.1 From e250b82377aa9c1433c6235501c72dd079544c75 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 13 May 2024 22:26:19 +0200 Subject: Adjust logic. --- src/common/tusb_mcu.h | 5 +++-- src/device/dcd.h | 6 +++--- src/device/usbd.c | 20 +++++++++++--------- src/portable/synopsys/dwc2/dcd_dwc2.c | 4 ++-- src/tusb_option.h | 5 +++++ 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index e489e93e7..3a7d6ad33 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -195,6 +195,7 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32F4) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 + #define TUP_USBIP_DWC2_TEST_MODE // For most mcu, FS has 4, HS has 6. TODO 446/469/479 HS has 9 #define TUP_DCD_ENDPOINT_MAX 6 @@ -209,7 +210,7 @@ // MCU with on-chip HS Phy #if defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F733xx) #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS - #define TUP_USBIP_DWC2_TEST_MODE_SUPPORT + #define TUP_USBIP_DWC2_TEST_MODE #endif #elif TU_CHECK_MCU(OPT_MCU_STM32H7) @@ -278,7 +279,7 @@ defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) #define TUP_DCD_ENDPOINT_MAX 9 #define TUP_RHPORT_HIGHSPEED 1 - #define TUP_USBIP_DWC2_TEST_MODE_SUPPORT + #define TUP_USBIP_DWC2_TEST_MODE #else #define TUP_DCD_ENDPOINT_MAX 6 #endif diff --git a/src/device/dcd.h b/src/device/dcd.h index b71b99869..9447d6d9d 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -97,8 +97,7 @@ typedef struct TU_ATTR_ALIGNED(4) { }; } dcd_event_t; -typedef enum _test_mode_selector -{ +typedef enum { TEST_J = 1, TEST_K, TEST_SE0_NAK, @@ -158,12 +157,13 @@ void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK; // Enable/Disable Start-of-frame interrupt. Default is disabled void dcd_sof_enable(uint8_t rhport, bool en); +#if CFG_TUD_TEST_MODE // Check if the test mode is supported, returns true is test mode selector is supported bool dcd_check_test_mode_support(test_mode_t test_selector) TU_ATTR_WEAK; // Put device into a test mode (needs power cycle to quit) void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) TU_ATTR_WEAK; - +#endif //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ diff --git a/src/device/usbd.c b/src/device/usbd.c index 7dfdc8476..25d890dc7 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -313,8 +313,9 @@ TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request); static bool process_set_config(uint8_t rhport, uint8_t cfg_num); static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request); +#if CFG_TUD_TEST_MODE static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); - +#endif // from usbd_control.c void usbd_control_reset(void); void usbd_control_set_request(tusb_control_request_t const *request); @@ -766,16 +767,16 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const tud_control_status(rhport, p_request); break; - #if !defined(TUSB_NO_TEST_MODE_SUPPORT) +#if CFG_TUD_TEST_MODE // Support for TEST_MODE - case TUSB_REQ_FEATURE_TEST_MODE: + case TUSB_REQ_FEATURE_TEST_MODE: { // Only handle the test mode if supported and valid TU_VERIFY(dcd_enter_test_mode && dcd_check_test_mode_support && 0 == tu_u16_low(p_request->wIndex)); uint8_t selector = tu_u16_high(p_request->wIndex); // Stall request if the selected test mode isn't supported - if (!dcd_check_test_mode_support(selector)) + if (!dcd_check_test_mode_support((test_mode_t)selector)) { TU_LOG_USBD(" Unsupported Test Mode (test selector index: %d)\r\n", selector); @@ -788,8 +789,9 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const TU_LOG_USBD(" Enter Test Mode (test selector index: %d)\r\n", selector); usbd_control_set_complete_callback(process_test_mode_cb); - break; - #endif /* !TUSB_NO_TEST_MODE_SUPPORT */ + break; + } +#endif /* CFG_TUD_TEST_MODE */ // Stall unsupported feature selector default: return false; @@ -1121,7 +1123,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const } } -#if !defined(TUSB_NO_TEST_MODE_SUPPORT) +#if CFG_TUD_TEST_MODE static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { // At this point it should already be ensured that dcd_enter_test_mode() is defined @@ -1129,11 +1131,11 @@ static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_req // Only enter the test mode after the request for it has completed TU_VERIFY(CONTROL_STAGE_ACK == stage); - dcd_enter_test_mode(rhport, tu_u16_high(request->wIndex)); + dcd_enter_test_mode(rhport, (test_mode_t)tu_u16_high(request->wIndex)); return true; } -#endif /* !TUSB_NO_TEST_MODE_SUPPORT */ +#endif /* CFG_TUD_TEST_MODE */ //--------------------------------------------------------------------+ // DCD Event Handler diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index c9580655f..fd2f08453 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1195,7 +1195,7 @@ void dcd_int_handler(uint8_t rhport) { // } } -#if defined(TUP_USBIP_DWC2_TEST_MODE_SUPPORT) && !defined(TUSB_NO_TEST_MODE_SUPPORT) +#if defined(TUP_USBIP_DWC2_TEST_MODE) && CFG_TUD_TEST_MODE bool dcd_check_test_mode_support(test_mode_t test_selector) { // Check if test mode selector is unsupported @@ -1218,6 +1218,6 @@ void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) { dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (test_selector << DCTL_TCTL_Pos); } -#endif /* TUP_USBIP_DWC2_TEST_MODE_SUPPORT && !TUSB_NO_TEST_MODE_SUPPORT */ +#endif /* TUP_USBIP_DWC2_TEST_MODE && CFG_TUD_TEST_MODE */ #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 8d5527936..058427e0e 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -364,6 +364,11 @@ #define CFG_TUD_INTERFACE_MAX 16 #endif +// USB 2.0 compliance test mode support +#ifndef CFG_TUD_TEST_MODE + #define CFG_TUD_TEST_MODE 0 +#endif + //------------- Device Class Driver -------------// #ifndef CFG_TUD_BTH #define CFG_TUD_BTH 0 -- cgit v1.3.1 From ad734e658cc9e39021a93fc21e077f1b1709c0ff Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 13 May 2024 22:27:33 +0200 Subject: Remove dead code. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index fd2f08453..dbcd586c5 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1207,10 +1207,6 @@ bool dcd_check_test_mode_support(test_mode_t test_selector) { } void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) { - // Disable test mode if not supported as a fall back - if (!dcd_check_test_mode_support(test_selector)) { - test_selector = 0; - } // Get port address... dwc2_regs_t* dwc2 = DWC2_REG(rhport); -- cgit v1.3.1 From 3c24ba3ff2eb5fdb4e214f668a25ed2038a847ad Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Tue, 14 May 2024 12:44:36 +0700 Subject: build arm-clang on circleci with pull request (#2644) * Build arm-clang using circle ci (only on PR): cache most of mandatory deps, clang toolchain * update get_deps.py to include CMSIS_5 with --print + no arguments, prevent duplicated deps --- .circleci/config.yml | 117 +++++++++++++++++++++++++++++------- .github/actions/get_deps/action.yml | 2 +- .github/workflows/build.yml | 4 +- tools/get_deps.py | 8 +-- 4 files changed, 102 insertions(+), 29 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d91de8419..77ab30f00 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,33 +1,106 @@ -# Use the latest 2.1 version of CircleCI pipeline process engine. -# See: https://circleci.com/docs/configuration-reference version: 2.1 -# Define a job to be invoked later in a workflow. -# See: https://circleci.com/docs/jobs-steps/#jobs-overview & https://circleci.com/docs/configuration-reference/#jobs +commands: + setup-toolchain: + parameters: + toolchain: + type: string + toolchain_url: + type: string + steps: + - run: + name: Make toolchain cache key + command: echo "<< parameters.toolchain >>-<< parameters.toolchain_url>>" > toolchain_key + - restore_cache: + name: Restore Toolchain Cache + key: deps-{{ checksum "toolchain_key" }} + paths: + - ~/cache/<< parameters.toolchain >> + - run: + name: Install Toolchain + command: | + # Only download if folder does not exist (not cached) + if [ ! -d ~/cache/<< parameters.toolchain >> ]; then + mkdir -p ~/cache/<< parameters.toolchain >> + wget << parameters.toolchain_url>> -O toolchain.tar.gz + tar -C ~/cache/<< parameters.toolchain >> -xaf toolchain.tar.gz + fi + - save_cache: + name: Save Toolchain Cache + key: deps-{{ checksum "toolchain_key" }} + paths: + - ~/cache/<< parameters.toolchain >> + - run: + name: Setup build environment + command: | + echo "export PATH=$PATH:`echo ~/cache/<< parameters.toolchain >>/*/bin`" >> $BASH_ENV + # Install Ninja + NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-linux.zip + wget $NINJA_URL -O ninja-linux.zip + unzip ninja-linux.zip -d ~/bin + + get-deps: + parameters: + family: + type: string + steps: + - run: + name: Make deps cache key + command: | + python tools/get_deps.py --print > deps_key + - restore_cache: + name: Restore Dependencies Cache + key: deps-{{ checksum "deps_key" }} + paths: + - lib/CMSIS_5 + - lib/FreeRTOS-Kernel + - lib/lwip + - tools/uf2 + - run: + name: Get Dependencies + command: | + python tools/get_deps.py << parameters.family >> + - save_cache: + name: Save Dependencies Cache + key: deps-{{ checksum "deps_key" }} + paths: + - lib/CMSIS_5 + - lib/FreeRTOS-Kernel + - lib/lwip + - tools/uf2 + jobs: - say-hello: - # Specify the execution environment. You can specify an image from Docker Hub or use one of our convenience images from CircleCI's Developer Hub. - # See: https://circleci.com/docs/executor-intro/ & https://circleci.com/docs/configuration-reference/#executor-job + arm-clang: + parameters: + family: + type: string + build-system: + type: string + docker: - # Specify the version you desire here - # See: https://circleci.com/developer/images/image/cimg/base - image: cimg/base:current - - resource_class: small - - # Add steps to the job - # See: https://circleci.com/docs/jobs-steps/#steps-overview & https://circleci.com/docs/configuration-reference/#steps + resource_class: medium + environment: + TOOLCHAIN_URL: https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-17.0.1/LLVMEmbeddedToolchainForArm-17.0.1-Linux-x86_64.tar.xz steps: - # Checkout the code as the first step. - checkout + - setup-toolchain: + toolchain: clang + toolchain_url: $TOOLCHAIN_URL + - get-deps: + family: << parameters.family >> - run: - name: "Say hello" - command: "echo Hello, World!" + name: Build + command: python tools/build.py -s << parameters.build-system >> --toolchain clang << parameters.family >> -# Orchestrate jobs using workflows -# See: https://circleci.com/docs/workflows/ & https://circleci.com/docs/configuration-reference/#workflows workflows: - say-hello-workflow: # This is the name of the workflow, feel free to change it to better match your workflow. - # Inside the workflow, you define the jobs you want to run. + build: jobs: - - say-hello + - arm-clang: + matrix: + parameters: + build-system: + - cmake + #family: ['stm32f1'] + #family: ['stm32f1', 'stm32f2'] + family: ['imxrt', 'kinetis_k kinetis_kl kinetis_k32l2', 'lpc11 lpc13 lpc15', 'lpc17 lpc18 lpc40 lpc43', 'lpc51 lpc54 lpc55', 'nrf', 'samd11 samd21 saml2x', 'samd5x_e5x samg', 'stm32f0 stm32f1 stm32f2 stm32f3', 'stm32f4', 'stm32f7', 'stm32g0 stm32g4 stm32h5', 'stm32h7', 'stm32l4 stm32u5 stm32wb'] diff --git a/.github/actions/get_deps/action.yml b/.github/actions/get_deps/action.yml index 38b44a70e..eea241c6c 100644 --- a/.github/actions/get_deps/action.yml +++ b/.github/actions/get_deps/action.yml @@ -2,8 +2,8 @@ name: Get dependencies inputs: arg: + description: 'Arguments to get_deps.py' required: true - type: string runs: using: "composite" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2cd348847..78d95fbbc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,7 +58,7 @@ jobs: matrix: toolchain: - 'aarch64-gcc' -# - 'arm-clang' + # - 'arm-clang' # clang is built by circle-ci - 'arm-gcc' - 'msp430-gcc' - 'riscv-gcc' @@ -81,7 +81,7 @@ jobs: matrix: toolchain: - 'aarch64-gcc' - #- 'arm-clang' + # - 'arm-clang' # clang is built by circle-ci - 'arm-gcc' - 'msp430-gcc' - 'riscv-gcc' diff --git a/tools/get_deps.py b/tools/get_deps.py index 2c2f97b4b..87c1c5ccd 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -249,9 +249,6 @@ def main(): boards = args.board print_only = args.print - if len(families) == 0 and len(boards) == 0: - print("Warning: family and board are not specified, only fetching mandatory dependencies.") - status = 0 deps = list(deps_mandatory.keys()) @@ -267,11 +264,14 @@ def main(): for f in families: for d in deps_optional: - if f in deps_optional[d][2]: + if d not in deps and f in deps_optional[d][2]: deps.append(d) if print_only: pvalue = {} + # print only without arguments, always add CMSIS_5 + if len(families) == 0 and len(boards) == 0: + deps.append('lib/CMSIS_5') for d in deps: commit = deps_all[d][1] pvalue[d] = commit -- cgit v1.3.1 From aa2685536ba9e2fbbe3f350a5bb3c6709e586722 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 May 2024 16:00:15 +0700 Subject: implement max3421e hcd_edpt_abort_xfer() --- hw/bsp/nrf/family.cmake | 10 ++++ src/portable/analog/max3421/hcd_max3421.c | 80 +++++++++++++++++-------------- 2 files changed, 54 insertions(+), 36 deletions(-) diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index 5de69a8a3..9e86374dc 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -101,6 +101,15 @@ endfunction() #------------------------------------ # Functions #------------------------------------ + +#function(family_flash_adafruit_nrfutil TARGET) +# add_custom_target(${TARGET}-adafruit-nrfutil +# DEPENDS ${TARGET} +# COMMAND adafruit-nrfutil --verbose dfu serial --package $^ -p /dev/ttyACM0 -b 115200 --singlebank --touch 1200 +# ) +#endfunction() + + function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) @@ -133,4 +142,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_jlink(${TARGET}) +# family_flash_adafruit_nrfutil(${TARGET}) endfunction() diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 4dc93d2d8..d9b8e1fc3 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -174,7 +174,8 @@ enum { enum { EP_STATE_IDLE = 0, EP_STATE_COMPLETE = 1, - EP_STATE_ATTEMPT_1 = 2, // pending 1st attempt + EP_STATE_ABORTING = 2, + EP_STATE_ATTEMPT_1 = 3, // pending 1st attempt EP_STATE_ATTEMPT_MAX = 15 }; @@ -459,6 +460,7 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param; _tuh_cfg = cfg->max3421; + _tuh_cfg.max_nak = tu_min8(_tuh_cfg.max_nak, EP_STATE_ATTEMPT_MAX-EP_STATE_ATTEMPT_1); return true; } @@ -678,7 +680,6 @@ static void xact_generic(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { uint8_t const ep_num = tu_edpt_number(ep_addr); uint8_t const ep_dir = (uint8_t) tu_edpt_dir(ep_addr); - max3421_ep_t* ep = find_opened_ep(daddr, ep_num, ep_dir); TU_VERIFY(ep); @@ -702,14 +703,19 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf return true; } -// Abort a queued transfer. Note: it can only abort transfer that has not been started -// Return true if a queued transfer is aborted, false if there is no transfer to abort -bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { - (void) rhport; - (void) dev_addr; - (void) ep_addr; +bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { + uint8_t const ep_num = tu_edpt_number(ep_addr); + uint8_t const ep_dir = (uint8_t) tu_edpt_dir(ep_addr); + max3421_ep_t* ep = find_opened_ep(daddr, ep_num, ep_dir); + TU_VERIFY(ep); - return false; + if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) { + hcd_int_disable(rhport); + ep->state = EP_STATE_ABORTING; + hcd_int_enable(rhport); + } + + return true; } // Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked @@ -819,7 +825,6 @@ static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t re static void handle_xfer_done(uint8_t rhport, bool in_isr) { uint8_t const hrsl = reg_read(rhport, HRSL_ADDR, in_isr); uint8_t const hresult = hrsl & HRSL_RESULT_MASK; - uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK; uint8_t const hxfr_type = _hcd_data.hxfr & 0xf0; uint8_t const ep_dir = ((hxfr_type & HXFR_SETUP) || (hxfr_type & HXFR_OUT_NIN)) ? 0 : 1; @@ -829,34 +834,30 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { xfer_result_t xfer_result; switch(hresult) { - case HRSL_SUCCESS: - xfer_result = XFER_RESULT_SUCCESS; - break; - - case HRSL_STALL: - xfer_result = XFER_RESULT_STALLED; - break; - case HRSL_NAK: - if (ep_num == 0) { - // control endpoint -> retry immediately - hxfr_write(rhport, _hcd_data.hxfr, in_isr); + if (ep->state == EP_STATE_ABORTING) { + ep->state = EP_STATE_IDLE; } else { - if (ep->state < EP_STATE_ATTEMPT_MAX) { + if (ep_num == 0) { + // control endpoint -> retry immediately and return + hxfr_write(rhport, _hcd_data.hxfr, in_isr); + return; + } else if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) { ep->state++; } + } - max3421_ep_t * next_ep = find_next_pending_ep(ep); - if (ep == next_ep) { - // this endpoint is only one pending -> retry immediately - hxfr_write(rhport, _hcd_data.hxfr, in_isr); - } else if (next_ep) { - // switch to next pending endpoint TODO could have issue with double buffered if not clear previously out data - xact_generic(rhport, next_ep, true, in_isr); - } else { - // no more pending in this frame -> clear busy - atomic_flag_clear(&_hcd_data.busy); - } + max3421_ep_t * next_ep = find_next_pending_ep(ep); + if (ep == next_ep) { + // this endpoint is only one pending -> retry immediately + hxfr_write(rhport, _hcd_data.hxfr, in_isr); + } else if (next_ep) { + // switch to next pending endpoint + // TODO could have issue with double buffered if not clear previously out data + xact_generic(rhport, next_ep, true, in_isr); + } else { + // no more pending in this frame -> clear busy + atomic_flag_clear(&_hcd_data.busy); } return; @@ -864,6 +865,14 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { // occurred when initialized without any pending transfer. Skip for now return; + case HRSL_SUCCESS: + xfer_result = XFER_RESULT_SUCCESS; + break; + + case HRSL_STALL: + xfer_result = XFER_RESULT_STALLED; + break; + default: TU_LOG3("HRSL: %02X\r\n", hrsl); xfer_result = XFER_RESULT_FAILED; @@ -942,9 +951,8 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { if (hirq & HIRQ_FRAME_IRQ) { _hcd_data.frame_count++; + // reset all endpoints nak counter, retry with 1st pending ep. max3421_ep_t* ep_retry = NULL; - - // reset all endpoints attempt counter for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { max3421_ep_t* ep = &_hcd_data.ep[i]; if (ep->packet_size && ep->state > EP_STATE_ATTEMPT_1) { @@ -1004,7 +1012,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { // clear all interrupt except SNDBAV_IRQ (never clear by us). Note RCVDAV_IRQ, HXFRDN_IRQ already clear while processing hirq &= (uint8_t) ~HIRQ_SNDBAV_IRQ; - if ( hirq ) { + if (hirq) { hirq_write(rhport, hirq, in_isr); } } -- cgit v1.3.1 From 83499a2cd0f38807619c92d9a4060d20379556b9 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 May 2024 16:03:31 +0700 Subject: tweak action --- .github/actions/setup_toolchain/espressif/action.yml | 2 +- .github/workflows/codeql.yml | 6 +++--- .github/workflows/hil_test.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/actions/setup_toolchain/espressif/action.yml b/.github/actions/setup_toolchain/espressif/action.yml index a4c6127c6..494b7910e 100644 --- a/.github/actions/setup_toolchain/espressif/action.yml +++ b/.github/actions/setup_toolchain/espressif/action.yml @@ -23,7 +23,7 @@ runs: id: cache-toolchain-espressif with: path: ${{ steps.set-docker-image.outputs.DOCKER_IMAGE }} - key: ${{ runner.os }}-${{ inputs.toolchain }}-${{ inputs.toolchain_url }} + key: ${{ inputs.toolchain }}-${{ inputs.toolchain_url }} - name: Pull and Save Docker Image if: steps.cache-toolchain-espressif.outputs.cache-hit != 'true' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 1f7b60b9c..be4c2dd87 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -59,10 +59,10 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - - name: Install ARM GCC - uses: carlosperate/arm-none-eabi-gcc-action@v1 + - name: Setup Toolchain + uses: ./.github/actions/setup_toolchain with: - release: '11.2-2022.02' + toolchain: 'arm-gcc' # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index adb5bf00e..39a9060a2 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -41,7 +41,7 @@ jobs: echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT - - name: Setup ARM Toolchain + - name: Setup Toolchain uses: ./.github/actions/setup_toolchain with: toolchain: 'arm-gcc' -- cgit v1.3.1 From 50278211f4117079ce5eda396f68d802d9cda615 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 May 2024 16:20:01 +0700 Subject: circleci light build for merged commit to master --- .circleci/config.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 77ab30f00..2d4532aee 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -91,7 +91,13 @@ jobs: family: << parameters.family >> - run: name: Build - command: python tools/build.py -s << parameters.build-system >> --toolchain clang << parameters.family >> + command: | + # Only build one board per family for non PRs i.e commit to master + ONE_PER_FAMILY="" + if [ -z "$CIRCLE_PULL_REQUEST" ]; then + ONE_PER_FAMILY="--one-per-family" + fi + python tools/build.py $ONE_PER_FAMILY -s << parameters.build-system >> --toolchain clang << parameters.family >> workflows: build: -- cgit v1.3.1 From db60fa1c63ae58c205e43e144253dab6815bb2d1 Mon Sep 17 00:00:00 2001 From: Matthew Tran Date: Sun, 19 Nov 2023 18:26:40 -0800 Subject: add CH32V20x USB OTG/FS driver --- .gitignore | 1 + README.rst | 2 +- docs/reference/dependencies.rst | 1 + docs/reference/supported.rst | 6 +- examples/device/cdc_msc_freertos/skip.txt | 1 + examples/device/hid_composite_freertos/skip.txt | 1 + examples/device/msc_dual_lun/skip.txt | 1 + examples/device/video_capture/skip.txt | 1 + hw/bsp/ch32v20x/boards/nanoch32v203/board.h | 17 + hw/bsp/ch32v20x/boards/nanoch32v203/board.mk | 5 + hw/bsp/ch32v20x/ch32v20x_conf.h | 36 + hw/bsp/ch32v20x/ch32v20x_it.h | 15 + hw/bsp/ch32v20x/core_riscv.h | 572 ++++++++++++++ hw/bsp/ch32v20x/family.c | 82 ++ hw/bsp/ch32v20x/family.mk | 50 ++ hw/bsp/ch32v20x/system_ch32v20x.c | 976 ++++++++++++++++++++++++ hw/bsp/ch32v20x/system_ch32v20x.h | 29 + hw/bsp/ch32v20x/wch-riscv.cfg | 18 + hw/bsp/ch32v307/family.mk | 5 + hw/bsp/fomu/family.mk | 4 + hw/bsp/gd32vf103/family.mk | 5 + src/class/video/video_device.c | 2 +- src/common/tusb_mcu.h | 4 + src/portable/wch/ch32_usbfs_reg.h | 77 ++ src/portable/wch/dcd_ch32_usbfs.c | 304 ++++++++ src/tusb_option.h | 1 + tools/get_deps.py | 3 + tools/iar_template.ipcf | 1 + 28 files changed, 2215 insertions(+), 5 deletions(-) create mode 100644 hw/bsp/ch32v20x/boards/nanoch32v203/board.h create mode 100644 hw/bsp/ch32v20x/boards/nanoch32v203/board.mk create mode 100644 hw/bsp/ch32v20x/ch32v20x_conf.h create mode 100644 hw/bsp/ch32v20x/ch32v20x_it.h create mode 100644 hw/bsp/ch32v20x/core_riscv.h create mode 100644 hw/bsp/ch32v20x/family.c create mode 100644 hw/bsp/ch32v20x/family.mk create mode 100644 hw/bsp/ch32v20x/system_ch32v20x.c create mode 100644 hw/bsp/ch32v20x/system_ch32v20x.h create mode 100644 hw/bsp/ch32v20x/wch-riscv.cfg create mode 100644 src/portable/wch/ch32_usbfs_reg.h create mode 100644 src/portable/wch/dcd_ch32_usbfs.c diff --git a/.gitignore b/.gitignore index 56ae7600f..7a37d65dc 100644 --- a/.gitignore +++ b/.gitignore @@ -82,6 +82,7 @@ hw/mcu/st/stm32l5xx_hal_driver hw/mcu/st/stm32u5xx_hal_driver hw/mcu/st/stm32wbxx_hal_driver hw/mcu/ti +hw/mcu/wch/ch32v20x hw/mcu/wch/ch32v307 hw/mcu/wch/ch32f20x lib/CMSIS_5 diff --git a/README.rst b/README.rst index 8c3145d33..dbe75adc8 100644 --- a/README.rst +++ b/README.rst @@ -157,7 +157,7 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l +--------------+------------------------------------------------------------+ | ValentyUSB | eptri | +--------------+------------------------------------------------------------+ -| WCH | CH32F20x, CH32V307, | +| WCH | CH32F20x, CH32V20x, CH32V307 | +--------------+------------------------------------------------------------+ License diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index 6ba6692e9..3a98594ff 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -55,6 +55,7 @@ hw/mcu/st/stm32u5xx_hal_driver https://github.com/STMicroelectronics/ hw/mcu/st/stm32wbxx_hal_driver https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git 2c5f06638be516c1b772f768456ba637f077bac8 stm32wb hw/mcu/ti https://github.com/hathach/ti_driver.git 143ed6cc20a7615d042b03b21e070197d473e6e5 msp430 msp432e4 tm4c123 hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.git 77c4095087e5ed2c548ec9058e655d0b8757663b ch32f20x +hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git de6d68c654340d7f27b00cebbfc9aa2740a1abc2 ch32v20x hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 17761f5cf9dbbf2dcf665b7c04934188add20082 ch32v307 lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 20285262657d1b482d132d20d755c8c330d55c1f imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf ra saml2xstm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wb lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git 4ff01a7a4a51f53b44496aefee1e3c0071b7b173 all diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 7e7be25a4..3ca203e88 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -128,9 +128,9 @@ Supported MCUs +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| WCH | CH32V307 | ✔ | | ✔ | ch32v307 | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | CH32F20x | ✔ | | ✔ | ch32f205 | | +| WCH | CH32F20x | ✔ | | ✔ | ch32f205 | | +| | CH32V20x | ✔ | | ✖ | ch32v20x | | +| | CH32V307 | ✔ | | ✔ | ch32v307 | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ diff --git a/examples/device/cdc_msc_freertos/skip.txt b/examples/device/cdc_msc_freertos/skip.txt index eb434c23b..457ddb760 100644 --- a/examples/device/cdc_msc_freertos/skip.txt +++ b/examples/device/cdc_msc_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:CH32V307 mcu:CXD56 mcu:F1C100S diff --git a/examples/device/hid_composite_freertos/skip.txt b/examples/device/hid_composite_freertos/skip.txt index a6f96b288..6aaa27661 100644 --- a/examples/device/hid_composite_freertos/skip.txt +++ b/examples/device/hid_composite_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:CH32V307 mcu:CXD56 mcu:F1C100S diff --git a/examples/device/msc_dual_lun/skip.txt b/examples/device/msc_dual_lun/skip.txt index a9e3a99b1..4d607dc05 100644 --- a/examples/device/msc_dual_lun/skip.txt +++ b/examples/device/msc_dual_lun/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:SAMD11 mcu:MKL25ZXX family:espressif diff --git a/examples/device/video_capture/skip.txt b/examples/device/video_capture/skip.txt index 5898664a2..714cabeec 100644 --- a/examples/device/video_capture/skip.txt +++ b/examples/device/video_capture/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.h b/hw/bsp/ch32v20x/boards/nanoch32v203/board.h new file mode 100644 index 000000000..c8d28d90f --- /dev/null +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.h @@ -0,0 +1,17 @@ +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define LED_PORT GPIOA +#define LED_PIN GPIO_Pin_15 +#define LED_STATE_ON 0 +#define LED_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk b/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk new file mode 100644 index 000000000..75dc05457 --- /dev/null +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk @@ -0,0 +1,5 @@ +CFLAGS += \ + -DCH32V20x_D6 + +SRC_S += \ + $(CH32V20X_SDK_SRC)/Startup/startup_ch32v20x_D6.S diff --git a/hw/bsp/ch32v20x/ch32v20x_conf.h b/hw/bsp/ch32v20x/ch32v20x_conf.h new file mode 100644 index 000000000..949297fe6 --- /dev/null +++ b/hw/bsp/ch32v20x/ch32v20x_conf.h @@ -0,0 +1,36 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : ch32v20x_conf.h + * Author : WCH + * Version : V1.0.0 + * Date : 2021/06/06 + * Description : Library configuration file. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __CH32V20x_CONF_H +#define __CH32V20x_CONF_H + +#include "ch32v20x_adc.h" +#include "ch32v20x_bkp.h" +#include "ch32v20x_can.h" +#include "ch32v20x_crc.h" +#include "ch32v20x_dbgmcu.h" +#include "ch32v20x_dma.h" +#include "ch32v20x_exti.h" +#include "ch32v20x_flash.h" +#include "ch32v20x_gpio.h" +#include "ch32v20x_i2c.h" +#include "ch32v20x_iwdg.h" +#include "ch32v20x_pwr.h" +#include "ch32v20x_rcc.h" +#include "ch32v20x_rtc.h" +#include "ch32v20x_spi.h" +#include "ch32v20x_tim.h" +#include "ch32v20x_usart.h" +#include "ch32v20x_wwdg.h" +#include "ch32v20x_it.h" +#include "ch32v20x_misc.h" + +#endif /* __CH32V20x_CONF_H */ diff --git a/hw/bsp/ch32v20x/ch32v20x_it.h b/hw/bsp/ch32v20x/ch32v20x_it.h new file mode 100644 index 000000000..e49c61ae2 --- /dev/null +++ b/hw/bsp/ch32v20x/ch32v20x_it.h @@ -0,0 +1,15 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : ch32v20x_it.h + * Author : WCH + * Version : V1.0.0 + * Date : 2021/06/06 + * Description : This file contains the headers of the interrupt handlers. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __CH32V20x_IT_H +#define __CH32V20x_IT_H + +#endif /* __CH32V20x_IT_H */ diff --git a/hw/bsp/ch32v20x/core_riscv.h b/hw/bsp/ch32v20x/core_riscv.h new file mode 100644 index 000000000..be1b52a6c --- /dev/null +++ b/hw/bsp/ch32v20x/core_riscv.h @@ -0,0 +1,572 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : core_riscv.h + * Author : WCH + * Version : V1.0.0 + * Date : 2021/06/06 + * Description : RISC-V Core Peripheral Access Layer Header File for CH32V20x +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __CORE_RISCV_H__ +#define __CORE_RISCV_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* IO definitions */ +#ifdef __cplusplus + #define __I volatile /* defines 'read only' permissions */ +#else + #define __I volatile const /* defines 'read only' permissions */ +#endif +#define __O volatile /* defines 'write only' permissions */ +#define __IO volatile /* defines 'read / write' permissions */ + +/* Standard Peripheral Library old types (maintained for legacy purpose) */ +typedef __I uint64_t vuc64; /* Read Only */ +typedef __I uint32_t vuc32; /* Read Only */ +typedef __I uint16_t vuc16; /* Read Only */ +typedef __I uint8_t vuc8; /* Read Only */ + +typedef const uint64_t uc64; /* Read Only */ +typedef const uint32_t uc32; /* Read Only */ +typedef const uint16_t uc16; /* Read Only */ +typedef const uint8_t uc8; /* Read Only */ + +typedef __I int64_t vsc64; /* Read Only */ +typedef __I int32_t vsc32; /* Read Only */ +typedef __I int16_t vsc16; /* Read Only */ +typedef __I int8_t vsc8; /* Read Only */ + +typedef const int64_t sc64; /* Read Only */ +typedef const int32_t sc32; /* Read Only */ +typedef const int16_t sc16; /* Read Only */ +typedef const int8_t sc8; /* Read Only */ + +typedef __IO uint64_t vu64; +typedef __IO uint32_t vu32; +typedef __IO uint16_t vu16; +typedef __IO uint8_t vu8; + +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +typedef __IO int64_t vs64; +typedef __IO int32_t vs32; +typedef __IO int16_t vs16; +typedef __IO int8_t vs8; + +typedef int64_t s64; +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; + +typedef enum {NoREADY = 0, READY = !NoREADY} ErrorStatus; + +typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; + +typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; + +#define RV_STATIC_INLINE static inline + +/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */ +typedef struct{ + __I uint32_t ISR[8]; + __I uint32_t IPR[8]; + __IO uint32_t ITHRESDR; + __IO uint32_t RESERVED; + __IO uint32_t CFGR; + __I uint32_t GISR; + __IO uint8_t VTFIDR[4]; + uint8_t RESERVED0[12]; + __IO uint32_t VTFADDR[4]; + uint8_t RESERVED1[0x90]; + __O uint32_t IENR[8]; + uint8_t RESERVED2[0x60]; + __O uint32_t IRER[8]; + uint8_t RESERVED3[0x60]; + __O uint32_t IPSR[8]; + uint8_t RESERVED4[0x60]; + __O uint32_t IPRR[8]; + uint8_t RESERVED5[0x60]; + __IO uint32_t IACTR[8]; + uint8_t RESERVED6[0xE0]; + __IO uint8_t IPRIOR[256]; + uint8_t RESERVED7[0x810]; + __IO uint32_t SCTLR; +}PFIC_Type; + +/* memory mapped structure for SysTick */ +typedef struct +{ + __IO uint32_t CTLR; + __IO uint32_t SR; + __IO uint64_t CNT; + __IO uint64_t CMP; +}SysTick_Type; + +#define PFIC ((PFIC_Type *) 0xE000E000 ) +#define NVIC PFIC +#define NVIC_KEY1 ((uint32_t)0xFA050000) +#define NVIC_KEY2 ((uint32_t)0xBCAF0000) +#define NVIC_KEY3 ((uint32_t)0xBEEF0000) + +#define SysTick ((SysTick_Type *) 0xE000F000) + +/********************************************************************* + * @fn __enable_irq + * + * @brief Enable Global Interrupt + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __enable_irq(void) +{ + __asm volatile ("csrw 0x800, %0" : : "r" (0x6088) ); +} + +/********************************************************************* + * @fn __disable_irq + * + * @brief Disable Global Interrupt + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __disable_irq(void) +{ + __asm volatile ("csrw 0x800, %0" : : "r" (0x6000) ); +} + +/********************************************************************* + * @fn __NOP + * + * @brief nop + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __NOP(void) +{ + __asm volatile ("nop"); +} + +/********************************************************************* + * @fn NVIC_EnableIRQ + * + * @brief Disable Interrupt + * + * @param IRQn - Interrupt Numbers + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + +/********************************************************************* + * @fn NVIC_DisableIRQ + * + * @brief Disable Interrupt + * + * @param IRQn - Interrupt Numbers + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + +/********************************************************************* + * @fn NVIC_GetStatusIRQ + * + * @brief Get Interrupt Enable State + * + * @param IRQn - Interrupt Numbers + * + * @return 1 - Interrupt Pending Enable + * 0 - Interrupt Pending Disable + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetStatusIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + +/********************************************************************* + * @fn NVIC_GetPendingIRQ + * + * @brief Get Interrupt Pending State + * + * @param IRQn - Interrupt Numbers + * + * @return 1 - Interrupt Pending Enable + * 0 - Interrupt Pending Disable + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + +/********************************************************************* + * @fn NVIC_SetPendingIRQ + * + * @brief Set Interrupt Pending + * + * @param IRQn - Interrupt Numbers + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + +/********************************************************************* + * @fn NVIC_ClearPendingIRQ + * + * @brief Clear Interrupt Pending + * + * @param IRQn - Interrupt Numbers + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + +/********************************************************************* + * @fn NVIC_GetActive + * + * @brief Get Interrupt Active State + * + * @param IRQn - Interrupt Numbers + * + * @return 1 - Interrupt Active + * 0 - Interrupt No Active + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + +/********************************************************************* + * @fn NVIC_SetPriority + * + * @brief Set Interrupt Priority + * + * @param IRQn - Interrupt Numbers + * priority - bit7 - Pre-emption Priority + * bit[6:5] - Subpriority + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority) +{ + NVIC->IPRIOR[(uint32_t)(IRQn)] = priority; +} + +/********************************************************************* + * @fn __WFI + * + * @brief Wait for Interrupt + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void) +{ + NVIC->SCTLR &= ~(1<<3); // wfi + asm volatile ("wfi"); +} + +/********************************************************************* + * @fn _SEV + * + * @brief Set Event + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _SEV(void) +{ + uint32_t t; + + t = NVIC->SCTLR; + NVIC->SCTLR |= (1<<3)|(1<<5); + NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5)); +} + +/********************************************************************* + * @fn _WFE + * + * @brief Wait for Events + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _WFE(void) +{ + NVIC->SCTLR |= (1<<3); + asm volatile ("wfi"); +} + +/********************************************************************* + * @fn __WFE + * + * @brief Wait for Events + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void) +{ + _SEV(); + _WFE(); + _WFE(); +} + +/********************************************************************* + * @fn SetVTFIRQ + * + * @brief Set VTF Interrupt + * + * @param addr - VTF interrupt service function base address. + * IRQn - Interrupt Numbers + * num - VTF Interrupt Numbers + * NewState - DISABLE or ENABLE + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){ + if(num > 3) return ; + + if (NewState != DISABLE) + { + NVIC->VTFIDR[num] = IRQn; + NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1); + } + else{ + NVIC->VTFIDR[num] = IRQn; + NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1)); + } +} + +/********************************************************************* + * @fn NVIC_SystemReset + * + * @brief Initiate a system reset request + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SystemReset(void) +{ + NVIC->CFGR = NVIC_KEY3|(1<<7); +} + +/********************************************************************* + * @fn __AMOADD_W + * + * @brief Atomic Add with 32bit value + * Atomically ADD 32bit value with value in memory using amoadd.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be ADDed + * + * @return return memory value + add value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOADD_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amoadd.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOAND_W + * + * @brief Atomic And with 32bit value + * Atomically AND 32bit value with value in memory using amoand.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be ANDed + * + * @return return memory value & and value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOAND_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amoand.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOMAX_W + * + * @brief Atomic signed MAX with 32bit value + * Atomically signed max compare 32bit value with value in memory using amomax.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be compared + * + * @return the bigger value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMAX_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amomax.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOMAXU_W + * + * @brief Atomic unsigned MAX with 32bit value + * Atomically unsigned max compare 32bit value with value in memory using amomaxu.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be compared + * + * @return return the bigger value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMAXU_W(volatile uint32_t *addr, uint32_t value) +{ + uint32_t result; + + __asm volatile ("amomaxu.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOMIN_W + * + * @brief Atomic signed MIN with 32bit value + * Atomically signed min compare 32bit value with value in memory using amomin.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be compared + * + * @return the smaller value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMIN_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amomin.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOMINU_W + * + * @brief Atomic unsigned MIN with 32bit value + * Atomically unsigned min compare 32bit value with value in memory using amominu.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be compared + * + * @return the smaller value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMINU_W(volatile uint32_t *addr, uint32_t value) +{ + uint32_t result; + + __asm volatile ("amominu.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOOR_W + * + * @brief Atomic OR with 32bit value + * Atomically OR 32bit value with value in memory using amoor.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be ORed + * + * @return return memory value | and value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOOR_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amoor.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOSWAP_W + * + * @brief Atomically swap new 32bit value into memory using amoswap.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * newval - New value to be stored into the address + * + * @return return the original value in memory + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOSWAP_W(volatile uint32_t *addr, uint32_t newval) +{ + uint32_t result; + + __asm volatile ("amoswap.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(newval) : "memory"); + return result; +} + +/********************************************************************* + * @fn __AMOXOR_W + * + * @brief Atomic XOR with 32bit value + * Atomically XOR 32bit value with value in memory using amoxor.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be XORed + * + * @return return memory value ^ and value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOXOR_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amoxor.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/* Core_Exported_Functions */ +extern uint32_t __get_MSTATUS(void); +extern void __set_MSTATUS(uint32_t value); +extern uint32_t __get_MISA(void); +extern void __set_MISA(uint32_t value); +extern uint32_t __get_MTVEC(void); +extern void __set_MTVEC(uint32_t value); +extern uint32_t __get_MSCRATCH(void); +extern void __set_MSCRATCH(uint32_t value); +extern uint32_t __get_MEPC(void); +extern void __set_MEPC(uint32_t value); +extern uint32_t __get_MCAUSE(void); +extern void __set_MCAUSE(uint32_t value); +extern uint32_t __get_MTVAL(void); +extern void __set_MTVAL(uint32_t value); +extern uint32_t __get_MVENDORID(void); +extern uint32_t __get_MARCHID(void); +extern uint32_t __get_MIMPID(void); +extern uint32_t __get_MHARTID(void); +extern uint32_t __get_SP(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/ch32v20x/family.c b/hw/bsp/ch32v20x/family.c new file mode 100644 index 000000000..247dacde6 --- /dev/null +++ b/hw/bsp/ch32v20x/family.c @@ -0,0 +1,82 @@ +#include +#include "ch32v20x.h" +#include "bsp/board_api.h" +#include "board.h" + +__attribute__((interrupt)) +void USBHD_IRQHandler(void) { + tud_int_handler(0); +} + +#if CFG_TUSB_OS == OPT_OS_NONE + +volatile uint32_t system_ticks = 0; + +__attribute__((interrupt)) +void SysTick_Handler(void) { + SysTick->SR = 0; + system_ticks++; +} + +uint32_t SysTick_Config(uint32_t ticks) { + NVIC_EnableIRQ(SysTicK_IRQn); + SysTick->CTLR = 0; + SysTick->SR = 0; + SysTick->CNT = 0; + SysTick->CMP = ticks-1; + SysTick->CTLR = 0xF; + return 0; +} + +uint32_t board_millis(void) { + return system_ticks; +} + +#endif + +void board_init(void) { + __disable_irq(); + +#if CFG_TUSB_OS == OPT_OS_NONE + SysTick_Config(SystemCoreClock / 1000); +#endif + + switch (SystemCoreClock) { + case 48000000: RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); break; + case 96000000: RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div2); break; + case 144000000: RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div3); break; + default: TU_ASSERT(0,); break; + } + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); + + LED_CLOCK_EN(); + GPIO_InitTypeDef GPIO_InitStructure = { + .GPIO_Pin = LED_PIN, + .GPIO_Mode = GPIO_Mode_Out_OD, + .GPIO_Speed = GPIO_Speed_50MHz, + }; + GPIO_Init(LED_PORT, &GPIO_InitStructure); + + __enable_irq(); + board_delay(2); +} + +void board_led_write(bool state) { + GPIO_WriteBit(LED_PORT, LED_PIN, state); +} + +uint32_t board_button_read(void) { + return false; +} + +int board_uart_read(uint8_t *buf, int len) { + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const *buf, int len) { + (void) buf; + (void) len; + return len; +} diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk new file mode 100644 index 000000000..2d94f19fb --- /dev/null +++ b/hw/bsp/ch32v20x/family.mk @@ -0,0 +1,50 @@ +# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +CROSS_COMPILE ?= riscv-none-elf- + +# Submodules +CH32V20X_SDK = hw/mcu/wch/ch32v20x +DEPS_SUBMODULES += $(CH32V20X_SDK) + +# WCH-SDK paths +CH32V20X_SDK_SRC = $(CH32V20X_SDK)/EVT/EXAM/SRC + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -march=rv32imac_zicsr \ + -mabi=ilp32 \ + -mcmodel=medany \ + -ffunction-sections \ + -fdata-sections \ + -ffat-lto-objects \ + -flto \ + -nostdlib -nostartfiles \ + -DCFG_TUSB_MCU=OPT_MCU_CH32V20X \ + -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED \ + +LDFLAGS_GCC += \ + -Wl,--gc-sections \ + -specs=nosys.specs \ + -specs=nano.specs \ + +LD_FILE = $(CH32V20X_SDK_SRC)/Ld/Link.ld + +SRC_C += \ + src/portable/wch/dcd_ch32_usbfs.c \ + $(CH32V20X_SDK_SRC)/Core/core_riscv.c \ + $(CH32V20X_SDK_SRC)/Peripheral/src/ch32v20x_gpio.c \ + $(CH32V20X_SDK_SRC)/Peripheral/src/ch32v20x_misc.c \ + $(CH32V20X_SDK_SRC)/Peripheral/src/ch32v20x_rcc.c \ + $(CH32V20X_SDK_SRC)/Peripheral/src/ch32v20x_usart.c \ + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(CH32V20X_SDK_SRC)/Peripheral/inc \ + +FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V + +# wch-link is not supported yet in official openOCD yet. We need to either use +# 1. download openocd as part of mounriver studio http://www.mounriver.com/download or +# 2. compiled from modified source https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz +flash: $(BUILD)/$(PROJECT).elf + openocd -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "flash write_image $<" -c reset -c exit diff --git a/hw/bsp/ch32v20x/system_ch32v20x.c b/hw/bsp/ch32v20x/system_ch32v20x.c new file mode 100644 index 000000000..588f3165a --- /dev/null +++ b/hw/bsp/ch32v20x/system_ch32v20x.c @@ -0,0 +1,976 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : system_ch32v20x.c + * Author : WCH + * Version : V1.0.0 + * Date : 2021/06/06 + * Description : CH32V20x Device Peripheral Access Layer System Source File. + * For HSE = 32Mhz (CH32V208x/CH32V203RBT6) + * For HSE = 8Mhz (other CH32V203x) +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#include "ch32v20x.h" + +/* +* Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after +* reset the HSI is used as SYSCLK source). +* If none of the define below is enabled, the HSI is used as System clock source. +*/ +//#define SYSCLK_FREQ_HSE HSE_VALUE +//#define SYSCLK_FREQ_48MHz_HSE 48000000 +//#define SYSCLK_FREQ_56MHz_HSE 56000000 +//#define SYSCLK_FREQ_72MHz_HSE 72000000 +#define SYSCLK_FREQ_96MHz_HSE 96000000 +//#define SYSCLK_FREQ_120MHz_HSE 120000000 +//#define SYSCLK_FREQ_144MHz_HSE 144000000 +//#define SYSCLK_FREQ_HSI HSI_VALUE +//#define SYSCLK_FREQ_48MHz_HSI 48000000 +//#define SYSCLK_FREQ_56MHz_HSI 56000000 +//#define SYSCLK_FREQ_72MHz_HSI 72000000 +//#define SYSCLK_FREQ_96MHz_HSI 96000000 +//#define SYSCLK_FREQ_120MHz_HSI 120000000 +//#define SYSCLK_FREQ_144MHz_HSI 144000000 + +/* Clock Definitions */ +#ifdef SYSCLK_FREQ_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_48MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_56MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_72MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_96MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_120MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_144MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_48MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_56MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_72MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_96MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_120MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_144MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSI; /* System Clock Frequency (Core Clock) */ +#else +uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */ + +#endif + +__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + +/* system_private_function_proto_types */ +static void SetSysClock(void); + +#ifdef SYSCLK_FREQ_HSE +static void SetSysClockToHSE( void ); +#elif defined SYSCLK_FREQ_48MHz_HSE +static void SetSysClockTo48_HSE( void ); +#elif defined SYSCLK_FREQ_56MHz_HSE +static void SetSysClockTo56_HSE( void ); +#elif defined SYSCLK_FREQ_72MHz_HSE +static void SetSysClockTo72_HSE( void ); +#elif defined SYSCLK_FREQ_96MHz_HSE +static void SetSysClockTo96_HSE( void ); +#elif defined SYSCLK_FREQ_120MHz_HSE +static void SetSysClockTo120_HSE( void ); +#elif defined SYSCLK_FREQ_144MHz_HSE +static void SetSysClockTo144_HSE( void ); +#elif defined SYSCLK_FREQ_48MHz_HSI +static void SetSysClockTo48_HSI( void ); +#elif defined SYSCLK_FREQ_56MHz_HSI +static void SetSysClockTo56_HSI( void ); +#elif defined SYSCLK_FREQ_72MHz_HSI +static void SetSysClockTo72_HSI( void ); +#elif defined SYSCLK_FREQ_96MHz_HSI +static void SetSysClockTo96_HSI( void ); +#elif defined SYSCLK_FREQ_120MHz_HSI +static void SetSysClockTo120_HSI( void ); +#elif defined SYSCLK_FREQ_144MHz_HSI +static void SetSysClockTo144_HSI( void ); + +#endif + +/********************************************************************* + * @fn SystemInit + * + * @brief Setup the microcontroller system Initialize the Embedded Flash Interface, + * the PLL and update the SystemCoreClock variable. + * + * @return none + */ +void SystemInit (void) +{ + RCC->CTLR |= (uint32_t)0x00000001; + RCC->CFGR0 &= (uint32_t)0xF8FF0000; + RCC->CTLR &= (uint32_t)0xFEF6FFFF; + RCC->CTLR &= (uint32_t)0xFFFBFFFF; + RCC->CFGR0 &= (uint32_t)0xFF80FFFF; + RCC->INTR = 0x009F0000; + SetSysClock(); +} + +/********************************************************************* + * @fn SystemCoreClockUpdate + * + * @brief Update SystemCoreClock variable according to Clock Register Values. + * + * @return none + */ +void SystemCoreClockUpdate (void) +{ + uint32_t tmp = 0, pllmull = 0, pllsource = 0, Pll_6_5 = 0; + + tmp = RCC->CFGR0 & RCC_SWS; + + switch (tmp) + { + case 0x00: + SystemCoreClock = HSI_VALUE; + break; + case 0x04: + SystemCoreClock = HSE_VALUE; + break; + case 0x08: + pllmull = RCC->CFGR0 & RCC_PLLMULL; + pllsource = RCC->CFGR0 & RCC_PLLSRC; + pllmull = ( pllmull >> 18) + 2; + + if(pllmull == 17) pllmull = 18; + + if (pllsource == 0x00) + { + if(EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE){ + SystemCoreClock = HSI_VALUE * pllmull; + } + else{ + SystemCoreClock = (HSI_VALUE >> 1) * pllmull; + } + } + else + { +#if defined (CH32V20x_D8W) + if((RCC->CFGR0 & (3<<22)) == (3<<22)) + { + SystemCoreClock = ((HSE_VALUE>>1)) * pllmull; + } + else +#endif + if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET) + { +#if defined (CH32V20x_D8) || defined (CH32V20x_D8W) + SystemCoreClock = ((HSE_VALUE>>2) >> 1) * pllmull; +#else + SystemCoreClock = (HSE_VALUE >> 1) * pllmull; +#endif + } + else + { +#if defined (CH32V20x_D8) || defined (CH32V20x_D8W) + SystemCoreClock = (HSE_VALUE>>2) * pllmull; +#else + SystemCoreClock = HSE_VALUE * pllmull; +#endif + } + } + + if(Pll_6_5 == 1) SystemCoreClock = (SystemCoreClock / 2); + + break; + default: + SystemCoreClock = HSI_VALUE; + break; + } + + tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)]; + SystemCoreClock >>= tmp; +} + +/********************************************************************* + * @fn SetSysClock + * + * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClock(void) +{ +#ifdef SYSCLK_FREQ_HSE + SetSysClockToHSE(); +#elif defined SYSCLK_FREQ_48MHz_HSE + SetSysClockTo48_HSE(); +#elif defined SYSCLK_FREQ_56MHz_HSE + SetSysClockTo56_HSE(); +#elif defined SYSCLK_FREQ_72MHz_HSE + SetSysClockTo72_HSE(); +#elif defined SYSCLK_FREQ_96MHz_HSE + SetSysClockTo96_HSE(); +#elif defined SYSCLK_FREQ_120MHz_HSE + SetSysClockTo120_HSE(); +#elif defined SYSCLK_FREQ_144MHz_HSE + SetSysClockTo144_HSE(); +#elif defined SYSCLK_FREQ_48MHz_HSI + SetSysClockTo48_HSI(); +#elif defined SYSCLK_FREQ_56MHz_HSI + SetSysClockTo56_HSI(); +#elif defined SYSCLK_FREQ_72MHz_HSI + SetSysClockTo72_HSI(); +#elif defined SYSCLK_FREQ_96MHz_HSI + SetSysClockTo96_HSI(); +#elif defined SYSCLK_FREQ_120MHz_HSI + SetSysClockTo120_HSI(); +#elif defined SYSCLK_FREQ_144MHz_HSI + SetSysClockTo144_HSI(); + +#endif + + /* If none of the define above is enabled, the HSI is used as System clock + * source (default after reset) + */ +} + +#ifdef SYSCLK_FREQ_HSE + +/********************************************************************* + * @fn SetSysClockToHSE + * + * @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockToHSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1; + + /* Select HSE as system clock source + * CH32V20x_D6 (HSE=8MHZ) + * CH32V20x_D8 (HSE=32MHZ) + * CH32V20x_D8W (HSE=32MHZ) + */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_HSE; + + /* Wait till HSE is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04) + { + } + } + else + { + /* If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_48MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo48_HSE + * + * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo48_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 6 = 48 MHz (HSE=8MHZ) + * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ) + * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ) + */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_56MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo56_HSE + * + * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo56_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 7 = 56 MHz (HSE=8MHZ) + * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ) + * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ) + */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_72MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo72_HSE + * + * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo72_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 9 = 72 MHz (HSE=8MHZ) + * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ) + * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ) + */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_96MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo96_HSE + * + * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo96_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8MHZ) + * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ) + * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ) + */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_120MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo120_HSE + * + * @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo120_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if(HSEStatus == (uint32_t)0x01) + { +#if defined (CH32V20x_D8W) + RCC->CFGR0 |= (uint32_t)(3<<22); + /* HCLK = SYSCLK/2 */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2; +#else + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; +#endif + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 15 = 120 MHz (HSE=8MHZ) + * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 15 = 120 MHz (HSE=32MHZ) + * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/2 * 15 = 240 MHz (HSE=32MHZ) + */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} +#elif defined SYSCLK_FREQ_144MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo144_HSE + * + * @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo144_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 18 = 144 MHz (HSE=8MHZ) + * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ) + * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ) + */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_48MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo48_HSI + * + * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo48_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#elif defined SYSCLK_FREQ_56MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo56_HSI + * + * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo56_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 7 = 48 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#elif defined SYSCLK_FREQ_72MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo72_HSI + * + * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo72_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#elif defined SYSCLK_FREQ_96MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo96_HSI + * + * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo96_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 12 = 96 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL12); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#elif defined SYSCLK_FREQ_120MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo120_HSI + * + * @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo120_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 15 = 120 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL15); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} +#elif defined SYSCLK_FREQ_144MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo144_HSI + * + * @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo144_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 18 = 144 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL18); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#endif diff --git a/hw/bsp/ch32v20x/system_ch32v20x.h b/hw/bsp/ch32v20x/system_ch32v20x.h new file mode 100644 index 000000000..eec7ccb15 --- /dev/null +++ b/hw/bsp/ch32v20x/system_ch32v20x.h @@ -0,0 +1,29 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : system_ch32v20x.h + * Author : WCH + * Version : V1.0.0 + * Date : 2021/06/06 + * Description : CH32V20x Device Peripheral Access Layer System Header File. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __SYSTEM_ch32v20x_H +#define __SYSTEM_ch32v20x_H + +#ifdef __cplusplus + extern "C" { +#endif + +extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */ + +/* System_Exported_Functions */ +extern void SystemInit(void); +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__CH32V20x_SYSTEM_H */ diff --git a/hw/bsp/ch32v20x/wch-riscv.cfg b/hw/bsp/ch32v20x/wch-riscv.cfg new file mode 100644 index 000000000..56a18d77e --- /dev/null +++ b/hw/bsp/ch32v20x/wch-riscv.cfg @@ -0,0 +1,18 @@ +#interface wlink +adapter driver wlinke +adapter speed 6000 +transport select sdi + +wlink_set_address 0x00000000 +set _CHIPNAME wch_riscv +sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 + +set _TARGETNAME $_CHIPNAME.cpu + +target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME +$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1 +set _FLASHNAME $_CHIPNAME.flash + +flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 + +echo "Ready for Remote Connections" diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index 003b90539..7232bfa08 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -4,6 +4,9 @@ # Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack CROSS_COMPILE ?= riscv-none-embed- +# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +#CROSS_COMPILE ?= riscv-none-elf- + # Submodules CH32V307_SDK = hw/mcu/wch/ch32v307 @@ -13,6 +16,8 @@ CH32V307_SDK_SRC = $(CH32V307_SDK)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 +# -march=rv32imac_zicsr + CFLAGS += \ -flto \ -msmall-data-limit=8 \ diff --git a/hw/bsp/fomu/family.mk b/hw/bsp/fomu/family.mk index d4b6eaea6..78f20d7db 100644 --- a/hw/bsp/fomu/family.mk +++ b/hw/bsp/fomu/family.mk @@ -1,6 +1,10 @@ # Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack CROSS_COMPILE = riscv-none-embed- +# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +# CROSS_COMPILE = riscv-none-elf- +# -march=rv32i_zicsr + CPU_CORE ?= rv32i-ilp32 CFLAGS += \ diff --git a/hw/bsp/gd32vf103/family.mk b/hw/bsp/gd32vf103/family.mk index 28e48a6b5..646564eae 100644 --- a/hw/bsp/gd32vf103/family.mk +++ b/hw/bsp/gd32vf103/family.mk @@ -7,6 +7,9 @@ # Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack CROSS_COMPILE ?= riscv-none-embed- +# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +# CROSS_COMPILE ?= riscv-none-elf- + # Submodules NUCLEI_SDK = hw/mcu/gd/nuclei-sdk @@ -19,6 +22,8 @@ STARTUP_ASM = $(GD32VF103_SDK_SOC)/Common/Source/GCC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 +# -march=rv32imac_zicsr + CFLAGS += \ -mcmodel=medlow \ -mstrict-align \ diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 4218835aa..974289b69 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -609,7 +609,7 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); tusb_desc_cs_video_frm_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); - uint_fast32_t interval, interval_ms; + uint_fast32_t interval, interval_ms = 0; switch (request) { case VIDEO_REQUEST_GET_MAX: { uint_fast32_t min_interval, max_interval; diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 3a7d6ad33..eab112015 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -410,6 +410,10 @@ #elif TU_CHECK_MCU(OPT_MCU_CH32F20X) #define TUP_DCD_ENDPOINT_MAX 16 #define TUP_RHPORT_HIGHSPEED 1 + +#elif TU_CHECK_MCU(OPT_MCU_CH32V20X) + #define TUP_DCD_ENDPOINT_MAX 8 + #endif diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h new file mode 100644 index 000000000..3b8e49ae2 --- /dev/null +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -0,0 +1,77 @@ +#ifndef USB_CH32_USBFS_REG_H +#define USB_CH32_USBFS_REG_H + +#if (CFG_TUSB_MCU == OPT_MCU_CH32V20X) +#include +#endif + +// CTRL +#define USBFS_CTRL_DMA_EN (1 << 0) +#define USBFS_CTRL_CLR_ALL (1 << 1) +#define USBFS_CTRL_RESET_SIE (1 << 2) +#define USBFS_CTRL_INT_BUSY (1 << 3) +#define USBFS_CTRL_SYS_CTRL (1 << 4) +#define USBFS_CTRL_DEV_PUEN (1 << 5) +#define USBFS_CTRL_LOW_SPEED (1 << 6) +#define USBFS_CTRL_HOST_MODE (1 << 7) + +// INT_EN +#define USBFS_INT_EN_BUS_RST (1 << 0) +#define USBFS_INT_EN_DETECT (1 << 0) +#define USBFS_INT_EN_TRANSFER (1 << 1) +#define USBFS_INT_EN_SUSPEND (1 << 2) +#define USBFS_INT_EN_HST_SOF (1 << 3) +#define USBFS_INT_EN_FIFO_OV (1 << 4) +#define USBFS_INT_EN_DEV_NAK (1 << 6) +#define USBFS_INT_EN_DEV_SOF (1 << 7) + +// INT_FG +#define USBFS_INT_FG_BUS_RST (1 << 0) +#define USBFS_INT_FG_DETECT (1 << 0) +#define USBFS_INT_FG_TRANSFER (1 << 1) +#define USBFS_INT_FG_SUSPEND (1 << 2) +#define USBFS_INT_FG_HST_SOF (1 << 3) +#define USBFS_INT_FG_FIFO_OV (1 << 4) +#define USBFS_INT_FG_SIE_FREE (1 << 5) +#define USBFS_INT_FG_TOG_OK (1 << 6) +#define USBFS_INT_FG_IS_NAK (1 << 7) + +// INT_ST +#define USBFS_INT_ST_MASK_UIS_ENDP(x) (((x) >> 0) & 0x0F) +#define USBFS_INT_ST_MASK_UIS_TOKEN(x) (((x) >> 4) & 0x03) + +// UDEV_CTRL +#define USBFS_UDEV_CTRL_PORT_EN (1 << 0) +#define USBFS_UDEV_CTRL_GP_BIT (1 << 1) +#define USBFS_UDEV_CTRL_LOW_SPEED (1 << 2) +#define USBFS_UDEV_CTRL_DM_PIN (1 << 4) +#define USBFS_UDEV_CTRL_DP_PIN (1 << 5) +#define USBFS_UDEV_CTRL_PD_DIS (1 << 7) + +// TX_CTRL +#define USBFS_EP_T_RES_MASK (3 << 0) +#define USBFS_EP_T_TOG (1 << 2) +#define USBFS_EP_T_AUTO_TOG (1 << 3) + +#define USBFS_EP_T_RES_ACK (0 << 0) +#define USBFS_EP_T_RES_NYET (1 << 0) +#define USBFS_EP_T_RES_NAK (2 << 0) +#define USBFS_EP_T_RES_STALL (3 << 0) + +// RX_CTRL +#define USBFS_EP_R_RES_MASK (3 << 0) +#define USBFS_EP_R_TOG (1 << 2) +#define USBFS_EP_R_AUTO_TOG (1 << 3) + +#define USBFS_EP_R_RES_ACK (0 << 0) +#define USBFS_EP_R_RES_NYET (1 << 0) +#define USBFS_EP_R_RES_NAK (2 << 0) +#define USBFS_EP_R_RES_STALL (3 << 0) + +// token PID +#define PID_OUT 0 +#define PID_SOF 1 +#define PID_IN 2 +#define PID_SETUP 3 + +#endif // USB_CH32_USBFS_REG_H diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c new file mode 100644 index 000000000..256c46696 --- /dev/null +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -0,0 +1,304 @@ +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X) + +#include +#include "device/dcd.h" +#include "ch32_usbfs_reg.h" + +/* private defines */ +#define EP_MAX (8) + +#define EP_DMA(ep) ((&USBOTG_FS->UEP0_DMA)[ep]) +#define EP_TX_LEN(ep) ((&USBOTG_FS->UEP0_TX_LEN)[2 * ep]) +#define EP_TX_CTRL(ep) ((&USBOTG_FS->UEP0_TX_CTRL)[4 * ep]) +#define EP_RX_CTRL(ep) ((&USBOTG_FS->UEP0_RX_CTRL)[4 * ep]) + +/* private data */ +struct usb_xfer { + bool valid; + uint8_t *buffer; + size_t len; + size_t processed_len; + size_t max_size; +}; + +static struct { + bool ep0_tog; + bool isochronous[EP_MAX]; + struct usb_xfer xfer[EP_MAX][2]; + TU_ATTR_ALIGNED(4) uint8_t buffer[EP_MAX][2][64]; + TU_ATTR_ALIGNED(4) struct { + // OUT transfers >64 bytes will overwrite queued IN data! + uint8_t out[64]; + uint8_t in[1023]; + uint8_t pad; + } ep3_buffer; +} data; + +/* private helpers */ +static void update_in(uint8_t rhport, uint8_t ep, bool force) { + struct usb_xfer *xfer = &data.xfer[ep][TUSB_DIR_IN]; + if (xfer->valid) { + if (force || xfer->len) { + size_t len = TU_MIN(xfer->max_size, xfer->len); + if (ep == 0) { + memcpy(data.buffer[ep][TUSB_DIR_OUT], xfer->buffer, len); // ep0 uses same chunk + } else if (ep == 3) { + memcpy(data.ep3_buffer.in, xfer->buffer, len); + } else { + memcpy(data.buffer[ep][TUSB_DIR_IN], xfer->buffer, len); + } + xfer->buffer += len; + xfer->len -= len; + xfer->processed_len += len; + + EP_TX_LEN(ep) = len; + if (ep == 0) { + EP_TX_CTRL(0) = USBFS_EP_T_RES_ACK | (data.ep0_tog ? USBFS_EP_T_TOG : 0); + data.ep0_tog = !data.ep0_tog; + } else if (data.isochronous[ep]) { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NYET; + } else { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_ACK; + } + } else { + xfer->valid = false; + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NAK; + dcd_event_xfer_complete(rhport, ep | TUSB_DIR_IN_MASK, xfer->processed_len, + XFER_RESULT_SUCCESS, true); + } + } +} + +static void update_out(uint8_t rhport, uint8_t ep, size_t rx_len) { + struct usb_xfer *xfer = &data.xfer[ep][TUSB_DIR_OUT]; + if (xfer->valid) { + size_t len = TU_MIN(xfer->max_size, TU_MIN(xfer->len, rx_len)); + if (ep == 3) { + memcpy(xfer->buffer, data.ep3_buffer.out, len); + } else { + memcpy(xfer->buffer, data.buffer[ep][TUSB_DIR_OUT], len); + } + xfer->buffer += len; + xfer->len -= len; + xfer->processed_len += len; + + if (xfer->len == 0 || len < xfer->max_size) { + xfer->valid = false; + dcd_event_xfer_complete(rhport, ep, xfer->processed_len, XFER_RESULT_SUCCESS, true); + } + + if (ep == 0) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + } + } +} + +/* public functions */ +void dcd_init(uint8_t rhport) { + // init registers + USBOTG_FS->BASE_CTRL = USBFS_CTRL_SYS_CTRL | USBFS_CTRL_INT_BUSY | USBFS_CTRL_DMA_EN; + USBOTG_FS->UDEV_CTRL = USBFS_UDEV_CTRL_PD_DIS | USBFS_UDEV_CTRL_PORT_EN; + USBOTG_FS->DEV_ADDR = 0x00; + + USBOTG_FS->INT_FG = 0xFF; + USBOTG_FS->INT_EN = USBFS_INT_EN_BUS_RST | USBFS_INT_EN_TRANSFER | USBFS_INT_EN_SUSPEND; + + // setup endpoint 0 + EP_DMA(0) = (uint32_t) &data.buffer[0][0]; + EP_TX_LEN(0) = 0; + EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + + // enable other endpoints but NAK everything + USBOTG_FS->UEP4_1_MOD = 0xCC; + USBOTG_FS->UEP2_3_MOD = 0xCC; + USBOTG_FS->UEP5_6_MOD = 0xCC; + USBOTG_FS->UEP7_MOD = 0x0C; + + for (uint8_t ep = 1; ep < EP_MAX; ep++) { + EP_DMA(ep) = (uint32_t) &data.buffer[ep][0]; + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NAK; + } + EP_DMA(3) = (uint32_t) &data.ep3_buffer.out[0]; + + dcd_connect(rhport); +} + +void dcd_int_handler(uint8_t rhport) { + (void) rhport; + uint8_t status = USBOTG_FS->INT_FG; + if (status & USBFS_INT_FG_TRANSFER) { + uint8_t ep = USBFS_INT_ST_MASK_UIS_ENDP(USBOTG_FS->INT_ST); + uint8_t token = USBFS_INT_ST_MASK_UIS_TOKEN(USBOTG_FS->INT_ST); + + switch (token) { + case PID_OUT: { + uint16_t rx_len = USBOTG_FS->RX_LEN; + update_out(rhport, ep, rx_len); + break; + } + + case PID_IN: + update_in(rhport, ep, false); + break; + + case PID_SETUP: + data.ep0_tog = true; + dcd_event_setup_received(rhport, &data.buffer[0][TUSB_DIR_OUT][0], true); + break; + } + + USBOTG_FS->INT_FG = USBFS_INT_FG_TRANSFER; + } else if (status & USBFS_INT_FG_BUS_RST) { + data.ep0_tog = true; + data.xfer[0][TUSB_DIR_OUT].max_size = 64; + data.xfer[0][TUSB_DIR_IN].max_size = 64; + + dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); + + USBOTG_FS->DEV_ADDR = 0x00; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + + USBOTG_FS->INT_FG = USBFS_INT_FG_BUS_RST; + } else if (status & USBFS_INT_FG_SUSPEND) { + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SUSPEND }; + dcd_event_handler(&event, true); + USBOTG_FS->INT_FG = USBFS_INT_FG_SUSPEND; + } +} + +void dcd_int_enable(uint8_t rhport) { + (void) rhport; + NVIC_EnableIRQ(USBHD_IRQn); +} + +void dcd_int_disable(uint8_t rhport) { + (void) rhport; + NVIC_DisableIRQ(USBHD_IRQn); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { + (void) dev_addr; + dcd_edpt_xfer(rhport, 0x80, NULL, 0); // zlp status response +} + +void dcd_remote_wakeup(uint8_t rhport) { + (void) rhport; + // TODO optional +} + +void dcd_connect(uint8_t rhport) { + (void) rhport; + USBOTG_FS->BASE_CTRL |= USBFS_CTRL_DEV_PUEN; +} + +void dcd_disconnect(uint8_t rhport) { + (void) rhport; + USBOTG_FS->BASE_CTRL &= ~USBFS_CTRL_DEV_PUEN; +} + +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { + (void) rhport; + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS) { + USBOTG_FS->DEV_ADDR = (uint8_t) request->wValue; + } + EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; +} + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { + (void) rhport; + uint8_t ep = tu_edpt_number(desc_ep->bEndpointAddress); + uint8_t dir = tu_edpt_dir(desc_ep->bEndpointAddress); + TU_ASSERT(ep < EP_MAX); + + data.isochronous[ep] = desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS; + data.xfer[ep][dir].max_size = tu_edpt_packet_size(desc_ep); + + if (ep != 0) { + if (dir == TUSB_DIR_OUT) { + if (data.isochronous[ep]) { + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NYET; + } else { + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_ACK; + } + } else { + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; + } + } + return true; +} + +void dcd_edpt_close_all(uint8_t rhport) { + (void) rhport; + // TODO optional +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + (void) ep_addr; + // TODO optional +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + + struct usb_xfer *xfer = &data.xfer[ep][dir]; + xfer->valid = true; + xfer->buffer = buffer; + xfer->len = total_bytes; + xfer->processed_len = 0; + + if (dir == TUSB_DIR_IN) { + update_in(rhport, ep, true); + } + return true; +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + if (ep == 0) { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_STALL; + } else { + EP_TX_LEN(0) = 0; + EP_TX_CTRL(0) = USBFS_EP_T_RES_STALL; + } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~USBFS_EP_R_RES_MASK) | USBFS_EP_R_RES_STALL; + } else { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~USBFS_EP_T_RES_MASK) | USBFS_EP_T_RES_STALL; + } + } +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + if (ep == 0) { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~(USBFS_EP_R_RES_MASK | USBFS_EP_R_TOG)) | USBFS_EP_R_RES_ACK; + } else { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK | USBFS_EP_T_TOG)) | USBFS_EP_T_RES_NAK; + } + } +} + +#endif // CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X) diff --git a/src/tusb_option.h b/src/tusb_option.h index 058427e0e..3d04825a4 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -181,6 +181,7 @@ // WCH #define OPT_MCU_CH32V307 2200 ///< WCH CH32V307 #define OPT_MCU_CH32F20X 2210 ///< WCH CH32F20x +#define OPT_MCU_CH32V20X 2220 ///< WCH CH32V20X // NXP LPC MCX diff --git a/tools/get_deps.py b/tools/get_deps.py index 87c1c5ccd..cf15126b3 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -168,6 +168,9 @@ deps_optional = { 'hw/mcu/ti': ['https://github.com/hathach/ti_driver.git', '143ed6cc20a7615d042b03b21e070197d473e6e5', 'msp430 msp432e4 tm4c'], + 'hw/mcu/wch/ch32v20x': ['https://github.com/openwch/ch32v20x.git', + 'de6d68c654340d7f27b00cebbfc9aa2740a1abc2', + 'ch32v20x'], 'hw/mcu/wch/ch32v307': ['https://github.com/openwch/ch32v307.git', '17761f5cf9dbbf2dcf665b7c04934188add20082', 'ch32v307'], diff --git a/tools/iar_template.ipcf b/tools/iar_template.ipcf index e72ec0ce2..33a6ef045 100644 --- a/tools/iar_template.ipcf +++ b/tools/iar_template.ipcf @@ -239,6 +239,7 @@ $TUSB_DIR$/src/portable/valentyusb/eptri/dcd_eptri.h + $TUSB_DIR$/src/portable/wch/dcd_ch32_usbfs.c $TUSB_DIR$/src/portable/wch/dcd_ch32_usbhs.c $TUSB_DIR$/src/portable/wch/ch32_usbhs_reg.h -- cgit v1.3.1 From 2a67ce773dcd68f7f8c4c07fce2e6e4f7947e03d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 May 2024 20:13:00 +0700 Subject: change default risv-gcc to riscv-none-elf- and add _zicsr extension add cmake for ch32v20x, skip freertos examples for CH32V20X, also skip net webserver due to lack of RAM update to use openocd with wlinke adapter --- .github/workflows/ci_set_matrix.py | 4 +- .idea/cmake.xml | 4 +- examples/build_system/cmake/cpu/rv32i-ilp32.cmake | 4 +- .../build_system/cmake/cpu/rv32imac-ilp32.cmake | 4 +- .../build_system/cmake/toolchain/riscv_gcc.cmake | 19 +++- examples/build_system/make/cpu/rv32i-ilp32.mk | 11 ++- examples/build_system/make/cpu/rv32imac-ilp32.mk | 10 +- .../device/audio_4_channel_mic_freertos/skip.txt | 1 + examples/device/audio_test_freertos/skip.txt | 1 + examples/device/net_lwip_webserver/skip.txt | 1 + examples/device/video_capture_2ch/skip.txt | 1 + hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake | 7 ++ hw/bsp/ch32v20x/family.cmake | 109 +++++++++++++++++++++ hw/bsp/ch32v20x/family.mk | 17 ++-- hw/bsp/ch32v20x/wch-riscv.cfg | 1 - hw/bsp/ch32v307/family.cmake | 1 - hw/bsp/ch32v307/family.mk | 8 +- hw/bsp/ch32v307/wch-riscv.cfg | 16 +-- hw/bsp/family_support.cmake | 1 + hw/bsp/fomu/family.mk | 6 +- hw/bsp/gd32vf103/family.mk | 7 +- src/portable/wch/dcd_ch32_usbfs.c | 8 ++ 22 files changed, 191 insertions(+), 50 deletions(-) create mode 100644 hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake create mode 100644 hw/bsp/ch32v20x/family.cmake diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 62239c9ad..c6f4e8fe2 100644 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -7,14 +7,14 @@ toolchain_list = { "arm-iar": "", "arm-gcc": "", "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", - "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v10.1.0-1.1/xpack-riscv-none-embed-gcc-10.1.0-1.1-linux-x64.tar.gz", + "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz" } # family: [supported toolchain] family_list = { "broadcom_32bit": ["arm-gcc"], "broadcom_64bit": ["aarch64-gcc"], - "ch32v307 fomu gd32vf103": ["riscv-gcc"], + "ch32v20x ch32v307 fomu gd32vf103": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"], "lpc11 lpc13 lpc15": ["arm-gcc", "arm-clang"], diff --git a/.idea/cmake.xml b/.idea/cmake.xml index bb13a0466..a34f19e1f 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -66,6 +66,7 @@ + @@ -103,6 +104,7 @@ + @@ -120,7 +122,6 @@ - @@ -130,6 +131,7 @@ + \ No newline at end of file diff --git a/examples/build_system/cmake/cpu/rv32i-ilp32.cmake b/examples/build_system/cmake/cpu/rv32i-ilp32.cmake index b4889e6ff..605c40ba1 100644 --- a/examples/build_system/cmake/cpu/rv32i-ilp32.cmake +++ b/examples/build_system/cmake/cpu/rv32i-ilp32.cmake @@ -1,13 +1,13 @@ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS - -march=rv32i + -march=rv32i_zicsr -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS - -march=rv32i + -march=rv32i_zicsr -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") diff --git a/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake b/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake index dd1bc0af7..584d90519 100644 --- a/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake +++ b/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake @@ -1,13 +1,13 @@ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS - -march=rv32imac + -march=rv32imac_zicsr -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS - -march=rv32imac + -march=rv32imac_zicsr -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") diff --git a/examples/build_system/cmake/toolchain/riscv_gcc.cmake b/examples/build_system/cmake/toolchain/riscv_gcc.cmake index 904b27294..d788df023 100644 --- a/examples/build_system/cmake/toolchain/riscv_gcc.cmake +++ b/examples/build_system/cmake/toolchain/riscv_gcc.cmake @@ -1,15 +1,24 @@ +# default Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +if (NOT DEFINED CROSS_COMPILE) + set(CROSS_COMPILE "riscv-none-elf-") +endif () + +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc) +endif () + if (NOT DEFINED CMAKE_C_COMPILER) - set(CMAKE_C_COMPILER "riscv-none-embed-gcc") + set(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc) endif () if (NOT DEFINED CMAKE_CXX_COMPILER) - set(CMAKE_CXX_COMPILER "riscv-none-embed-g++") + set(CMAKE_CXX_COMPILER ${CROSS_COMPILE}g++) endif () set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) -set(CMAKE_SIZE "riscv-none-embed-size" CACHE FILEPATH "") -set(CMAKE_OBJCOPY "riscv-none-embed-objcopy" CACHE FILEPATH "") -set(CMAKE_OBJDUMP "riscv-none-embed-objdump" CACHE FILEPATH "") +set(CMAKE_SIZE ${CROSS_COMPILE}size CACHE FILEPATH "") +set(CMAKE_OBJCOPY ${CROSS_COMPILE}objcopy CACHE FILEPATH "") +set(CMAKE_OBJDUMP ${CROSS_COMPILE}objdump CACHE FILEPATH "") include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) diff --git a/examples/build_system/make/cpu/rv32i-ilp32.mk b/examples/build_system/make/cpu/rv32i-ilp32.mk index a465baf4c..af764afc5 100644 --- a/examples/build_system/make/cpu/rv32i-ilp32.mk +++ b/examples/build_system/make/cpu/rv32i-ilp32.mk @@ -1,12 +1,15 @@ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ - -march=rv32i \ + -march=rv32i_zicsr \ -mabi=ilp32 \ -else ifeq ($(TOOLCHAIN),iar) - #CFLAGS += --cpu cortex-a53 - #ASFLAGS += --cpu cortex-a53 +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + -march=rv32i_zicsr \ + -mabi=ilp32 \ +else ifeq ($(TOOLCHAIN),iar) + $(error not support) endif # For freeRTOS port source diff --git a/examples/build_system/make/cpu/rv32imac-ilp32.mk b/examples/build_system/make/cpu/rv32imac-ilp32.mk index 2b6493e48..19c322ebc 100644 --- a/examples/build_system/make/cpu/rv32imac-ilp32.mk +++ b/examples/build_system/make/cpu/rv32imac-ilp32.mk @@ -1,11 +1,15 @@ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ - -march=rv32imac \ + -march=rv32imac_zicsr \ + -mabi=ilp32 \ + +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + -march=rv32imac_zicsr \ -mabi=ilp32 \ else ifeq ($(TOOLCHAIN),iar) - #CFLAGS += --cpu cortex-a53 - #ASFLAGS += --cpu cortex-a53 + $(error not support) endif diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt index 0b689192d..4769af009 100644 --- a/examples/device/audio_4_channel_mic_freertos/skip.txt +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:CH32V307 mcu:CXD56 mcu:F1C100S diff --git a/examples/device/audio_test_freertos/skip.txt b/examples/device/audio_test_freertos/skip.txt index a6f96b288..6aaa27661 100644 --- a/examples/device/audio_test_freertos/skip.txt +++ b/examples/device/audio_test_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:CH32V307 mcu:CXD56 mcu:F1C100S diff --git a/examples/device/net_lwip_webserver/skip.txt b/examples/device/net_lwip_webserver/skip.txt index 43cdab71a..51af58667 100644 --- a/examples/device/net_lwip_webserver/skip.txt +++ b/examples/device/net_lwip_webserver/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:LPC11UXX mcu:LPC13XX mcu:LPC15XX diff --git a/examples/device/video_capture_2ch/skip.txt b/examples/device/video_capture_2ch/skip.txt index 86697899b..1786297f9 100644 --- a/examples/device/video_capture_2ch/skip.txt +++ b/examples/device/video_capture_2ch/skip.txt @@ -2,6 +2,7 @@ mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 mcu:GD32VF103 +mcu:CH32V20X mcu:CH32V307 mcu:STM32L0 family:espressif diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake new file mode 100644 index 000000000..2699f3e15 --- /dev/null +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake @@ -0,0 +1,7 @@ +set(MCU_VARIANT D6) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + CH32V20x_D6 + ) +endfunction() diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake new file mode 100644 index 000000000..fb39e3630 --- /dev/null +++ b/hw/bsp/ch32v20x/family.cmake @@ -0,0 +1,109 @@ +include_guard() + +set(CH32_FAMILY ch32v20x) +set(SDK_DIR ${TOP}/hw/mcu/wch/${CH32_FAMILY}/EVT/EXAM/SRC) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR rv32imac-ilp32 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS CH32V20X CACHE INTERNAL "") +set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${SDK_DIR}/Ld/Link.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/Startup/startup_${CH32_FAMILY}_${MCU_VARIANT}.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/Core/core_riscv.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/Peripheral/inc + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC + -mcmodel=medany + ) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for MSP432E4") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_CH32V20X ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/wch/dcd_ch32_usbfs.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_openocd_wch(${TARGET}) +endfunction() diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index 2d94f19fb..7e290bb18 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -1,3 +1,9 @@ +# https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable +#CROSS_COMPILE ?= riscv32-unknown-elf- + +# Toolchain from https://nucleisys.com/download.php +#CROSS_COMPILE ?= riscv-nuclei-elf- + # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack CROSS_COMPILE ?= riscv-none-elf- @@ -9,23 +15,21 @@ DEPS_SUBMODULES += $(CH32V20X_SDK) CH32V20X_SDK_SRC = $(CH32V20X_SDK)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= rv32imac-ilp32 CFLAGS += \ - -march=rv32imac_zicsr \ - -mabi=ilp32 \ -mcmodel=medany \ -ffunction-sections \ -fdata-sections \ -ffat-lto-objects \ -flto \ - -nostdlib -nostartfiles \ -DCFG_TUSB_MCU=OPT_MCU_CH32V20X \ -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED \ LDFLAGS_GCC += \ -Wl,--gc-sections \ - -specs=nosys.specs \ - -specs=nano.specs \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ LD_FILE = $(CH32V20X_SDK_SRC)/Ld/Link.ld @@ -46,5 +50,6 @@ FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V # wch-link is not supported yet in official openOCD yet. We need to either use # 1. download openocd as part of mounriver studio http://www.mounriver.com/download or # 2. compiled from modified source https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz +OPENOCD ?= $(HOME)/app/riscv-openocd-wch/src/openocd flash: $(BUILD)/$(PROJECT).elf - openocd -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "flash write_image $<" -c reset -c exit + $(OPENOCD) -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "flash write_image $<" -c reset -c exit diff --git a/hw/bsp/ch32v20x/wch-riscv.cfg b/hw/bsp/ch32v20x/wch-riscv.cfg index 56a18d77e..aa35aa9c5 100644 --- a/hw/bsp/ch32v20x/wch-riscv.cfg +++ b/hw/bsp/ch32v20x/wch-riscv.cfg @@ -1,4 +1,3 @@ -#interface wlink adapter driver wlinke adapter speed 6000 transport select sdi diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake index 87a0f2eba..fb478d387 100644 --- a/hw/bsp/ch32v307/family.cmake +++ b/hw/bsp/ch32v307/family.cmake @@ -11,7 +11,6 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TO set(FAMILY_MCUS CH32V307 CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") -set(OPENOCD_OPTION2 "-c wlink_reset_resume") #------------------------------------ # BOARD_TARGET diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index 7232bfa08..df9ded4a0 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -1,11 +1,11 @@ # https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable #CROSS_COMPILE ?= riscv32-unknown-elf- -# Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack -CROSS_COMPILE ?= riscv-none-embed- +# Toolchain from https://nucleisys.com/download.php +#CROSS_COMPILE ?= riscv-nuclei-elf- # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack -#CROSS_COMPILE ?= riscv-none-elf- +CROSS_COMPILE ?= riscv-none-elf- # Submodules CH32V307_SDK = hw/mcu/wch/ch32v307 @@ -16,8 +16,6 @@ CH32V307_SDK_SRC = $(CH32V307_SDK)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 -# -march=rv32imac_zicsr - CFLAGS += \ -flto \ -msmall-data-limit=8 \ diff --git a/hw/bsp/ch32v307/wch-riscv.cfg b/hw/bsp/ch32v307/wch-riscv.cfg index 0d24d16ca..aa35aa9c5 100644 --- a/hw/bsp/ch32v307/wch-riscv.cfg +++ b/hw/bsp/ch32v307/wch-riscv.cfg @@ -1,13 +1,15 @@ -#interface wlink -adapter driver wlink -wlink_set -set _CHIPNAME riscv -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 +adapter driver wlinke +adapter speed 6000 +transport select sdi + +wlink_set_address 0x00000000 +set _CHIPNAME wch_riscv +sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME -$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1 +target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME +$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1 set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index df4f616ef..6eef5b88b 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -440,6 +440,7 @@ function(family_flash_openocd TARGET) endfunction() # Add flash openocd-wch target +# compiled from https://github.com/hathach/riscv-openocd-wch or https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz function(family_flash_openocd_wch TARGET) if (NOT DEFINED OPENOCD) set(OPENOCD $ENV{HOME}/app/riscv-openocd-wch/src/openocd) diff --git a/hw/bsp/fomu/family.mk b/hw/bsp/fomu/family.mk index 78f20d7db..69a546964 100644 --- a/hw/bsp/fomu/family.mk +++ b/hw/bsp/fomu/family.mk @@ -1,9 +1,5 @@ -# Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack -CROSS_COMPILE = riscv-none-embed- - # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack -# CROSS_COMPILE = riscv-none-elf- -# -march=rv32i_zicsr +CROSS_COMPILE = riscv-none-elf- CPU_CORE ?= rv32i-ilp32 diff --git a/hw/bsp/gd32vf103/family.mk b/hw/bsp/gd32vf103/family.mk index 646564eae..48588886c 100644 --- a/hw/bsp/gd32vf103/family.mk +++ b/hw/bsp/gd32vf103/family.mk @@ -4,11 +4,8 @@ # Toolchain from https://nucleisys.com/download.php #CROSS_COMPILE ?= riscv-nuclei-elf- -# Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack -CROSS_COMPILE ?= riscv-none-embed- - # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack -# CROSS_COMPILE ?= riscv-none-elf- +CROSS_COMPILE ?= riscv-none-elf- # Submodules NUCLEI_SDK = hw/mcu/gd/nuclei-sdk @@ -22,8 +19,6 @@ STARTUP_ASM = $(GD32VF103_SDK_SOC)/Common/Source/GCC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 -# -march=rv32imac_zicsr - CFLAGS += \ -mcmodel=medlow \ -mstrict-align \ diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 256c46696..83f625e21 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -201,6 +201,14 @@ void dcd_disconnect(uint8_t rhport) { USBOTG_FS->BASE_CTRL &= ~USBFS_CTRL_DEV_PUEN; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { (void) rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && -- cgit v1.3.1 From d3098747c03fe7f5d5d8b9a45ed4e7134fcaaf9d Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 16 May 2024 11:17:05 -0700 Subject: Add esp32c2 and esp32h2 for max3421 support --- src/common/tusb_mcu.h | 2 +- src/tusb_option.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 5a567f2d5..f4325e0d8 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -329,7 +329,7 @@ #define TUP_USBIP_DWC2 #define TUP_DCD_ENDPOINT_MAX 6 -#elif TU_CHECK_MCU(OPT_MCU_ESP32) && (CFG_TUD_ENABLED || !(defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)) +#elif TU_CHECK_MCU(OPT_MCU_ESP32, OPT_MCU_ESP32C2, OPT_MCU_ESP32C3, OPT_MCU_ESP32C6, OPT_MCU_ESP32H2) && (CFG_TUD_ENABLED || !(defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)) #error "MCUs are only supported with CFG_TUH_MAX3421 enabled" //--------------------------------------------------------------------+ diff --git a/src/tusb_option.h b/src/tusb_option.h index 3ead20ee7..3a5b1e961 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -122,6 +122,8 @@ #define OPT_MCU_ESP32 902 ///< Espressif ESP32 (for host max3421e) #define OPT_MCU_ESP32C3 903 ///< Espressif ESP32-C3 #define OPT_MCU_ESP32C6 904 ///< Espressif ESP32-C6 +#define OPT_MCU_ESP32C2 905 ///< Espressif ESP32-C2 +#define OPT_MCU_ESP32H2 906 ///< Espressif ESP32-H2 #define TUP_MCU_ESPRESSIF (CFG_TUSB_MCU >= 900 && CFG_TUSB_MCU < 1000) // check if Espressif MCU // Dialog -- cgit v1.3.1 From ab5f2768773634efe8c79add7e009e2e2ca63279 Mon Sep 17 00:00:00 2001 From: Matthew Tran Date: Fri, 17 May 2024 09:52:06 -0700 Subject: fix ep0 stall not clearing --- src/portable/wch/dcd_ch32_usbfs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 83f625e21..3af3ff6d7 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -148,6 +148,8 @@ void dcd_int_handler(uint8_t rhport) { case PID_SETUP: data.ep0_tog = true; + dcd_edpt_clear_stall(rhport, tu_edpt_addr(0, TUSB_DIR_IN)); // setup clears stall + dcd_edpt_clear_stall(rhport, tu_edpt_addr(0, TUSB_DIR_OUT)); dcd_event_setup_received(rhport, &data.buffer[0][TUSB_DIR_OUT][0], true); break; } @@ -261,10 +263,12 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to uint8_t dir = tu_edpt_dir(ep_addr); struct usb_xfer *xfer = &data.xfer[ep][dir]; + dcd_int_disable(rhport); xfer->valid = true; xfer->buffer = buffer; xfer->len = total_bytes; xfer->processed_len = 0; + dcd_int_enable(rhport); if (dir == TUSB_DIR_IN) { update_in(rhport, ep, true); -- cgit v1.3.1 From 5fee292606e4c5502b2172328c02d5df24eb0c7c Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 17 May 2024 16:13:59 +0700 Subject: temp code --- hw/bsp/ch32v307/family.c | 25 +++++++++++++++++++++++++ hw/bsp/ch32v307/family.cmake | 23 ++++++++++++++--------- src/common/tusb_mcu.h | 4 ++-- src/portable/wch/ch32_usbfs_reg.h | 9 ++++++++- src/portable/wch/dcd_ch32_usbfs.c | 2 +- 5 files changed, 50 insertions(+), 13 deletions(-) diff --git a/hw/bsp/ch32v307/family.c b/hw/bsp/ch32v307/family.c index 245fa5674..50e48e7df 100644 --- a/hw/bsp/ch32v307/family.c +++ b/hw/bsp/ch32v307/family.c @@ -46,6 +46,18 @@ __attribute__ ((used)) void USBHS_IRQHandler_impl (void) tud_int_handler(0); } + +void OTG_FS_IRQHandler (void) __attribute__((naked)); +void OTG_FS_IRQHandler (void) +{ + __asm volatile ("call OTG_FS_IRQHandler_impl; mret"); +} + +__attribute__ ((used)) void OTG_FS_IRQHandler_impl (void) +{ + tud_int_handler(0); +} + //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ @@ -72,6 +84,7 @@ void board_init(void) { usart_printf_init(115200); + #if 0 RCC_USBCLK48MConfig(RCC_USBCLK48MCLKSource_USBPHY); RCC_USBHSPLLCLKConfig(RCC_HSBHSPLLCLKSource_HSE); RCC_USBHSConfig(RCC_USBPLL_Div2); @@ -79,6 +92,18 @@ void board_init(void) { RCC_USBHSPHYPLLALIVEcmd(ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHS, ENABLE); + #else + uint8_t otg_div; + switch (SystemCoreClock) { + case 48000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div1; break; + case 96000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div2; break; + case 144000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div3; break; + default: TU_ASSERT(0,); break; + } + RCC_OTGFSCLKConfig(otg_div); + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); + #endif + GPIO_InitTypeDef GPIO_InitStructure = {0}; // LED diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake index fb478d387..8a4bd7730 100644 --- a/hw/bsp/ch32v307/family.cmake +++ b/hw/bsp/ch32v307/family.cmake @@ -1,5 +1,6 @@ include_guard() +set(CH32_FAMILY ch32v30x) set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v307/EVT/EXAM/SRC) # include board specific @@ -12,6 +13,8 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TO set(FAMILY_MCUS CH32V307 CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") +# Port0 Fullspeed, Port1 Highspeed + #------------------------------------ # BOARD_TARGET #------------------------------------ @@ -27,18 +30,18 @@ function(add_board_target BOARD_TARGET) set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) - set(STARTUP_FILE_GNU ${SDK_DIR}/Startup/startup_ch32v30x_D8C.S) + set(STARTUP_FILE_GNU ${SDK_DIR}/Startup/startup_${CH32_FAMILY}_D8C.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/Core/core_riscv.c - ${SDK_DIR}/Peripheral/src/ch32v30x_gpio.c - ${SDK_DIR}/Peripheral/src/ch32v30x_misc.c - ${SDK_DIR}/Peripheral/src/ch32v30x_rcc.c - ${SDK_DIR}/Peripheral/src/ch32v30x_usart.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ch32v30x_it.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_ch32v30x.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${CH32_FAMILY}_it.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${BOARD_TARGET} PUBLIC @@ -46,7 +49,8 @@ function(add_board_target BOARD_TARGET) ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) target_compile_definitions(${BOARD_TARGET} PUBLIC - BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + #BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED ) update_board(${BOARD_TARGET}) @@ -100,7 +104,8 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_CH32V307 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC - ${TOP}/src/portable/wch/dcd_ch32_usbhs.c + #${TOP}/src/portable/wch/dcd_ch32_usbhs.c + ${TOP}/src/portable/wch/dcd_ch32_usbfs.c ) target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index eab112015..e313fea05 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -404,8 +404,8 @@ //------------- WCH -------------// #elif TU_CHECK_MCU(OPT_MCU_CH32V307) - #define TUP_DCD_ENDPOINT_MAX 16 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_DCD_ENDPOINT_MAX 8 +// #define TUP_RHPORT_HIGHSPEED 1 #elif TU_CHECK_MCU(OPT_MCU_CH32F20X) #define TUP_DCD_ENDPOINT_MAX 16 diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h index 3b8e49ae2..d5341f3a8 100644 --- a/src/portable/wch/ch32_usbfs_reg.h +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -1,8 +1,15 @@ #ifndef USB_CH32_USBFS_REG_H #define USB_CH32_USBFS_REG_H -#if (CFG_TUSB_MCU == OPT_MCU_CH32V20X) +#if (CFG_TUSB_MCU == OPT_MCU_CH32V307) +#include +#define USBHD_IRQn OTG_FS_IRQn + +#elif (CFG_TUSB_MCU == OPT_MCU_CH32V20X) #include + +#elif (CFG_TUSB_MCU == OPT_MCU_CH32F20X) +#include #endif // CTRL diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 3af3ff6d7..3e4b6cae5 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -1,6 +1,6 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X) +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X || CFG_TUSB_MCU == OPT_MCU_CH32V307) #include #include "device/dcd.h" -- cgit v1.3.1 From 4a5fee503b1e3783301cde9b605ef30052623327 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 20 May 2024 13:24:24 +0700 Subject: - update ch203 family to allow to specify flash and ram size. Introduce - add ch32v203_ro_1v0 board - CFG_EXAMPLE_MSC_DUAL_READONLY to build msc_dual_lun for ch32v203 --- examples/device/msc_dual_lun/skip.txt | 1 - examples/device/msc_dual_lun/src/msc_disk_dual.c | 85 +++++++++------------- hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.cmake | 10 +++ hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h | 17 +++++ hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.mk | 7 ++ hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake | 5 +- hw/bsp/ch32v20x/boards/nanoch32v203/board.mk | 10 ++- hw/bsp/ch32v20x/family.cmake | 22 +++--- hw/bsp/ch32v20x/family.mk | 27 ++++--- hw/bsp/ch32v20x/linker/ch32v20x.ld | 1 + 10 files changed, 106 insertions(+), 79 deletions(-) create mode 100644 hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.cmake create mode 100644 hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h create mode 100644 hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.mk create mode 100644 hw/bsp/ch32v20x/linker/ch32v20x.ld diff --git a/examples/device/msc_dual_lun/skip.txt b/examples/device/msc_dual_lun/skip.txt index 4d607dc05..a9e3a99b1 100644 --- a/examples/device/msc_dual_lun/skip.txt +++ b/examples/device/msc_dual_lun/skip.txt @@ -1,4 +1,3 @@ -mcu:CH32V20X mcu:SAMD11 mcu:MKL25ZXX family:espressif diff --git a/examples/device/msc_dual_lun/src/msc_disk_dual.c b/examples/device/msc_dual_lun/src/msc_disk_dual.c index 4f0f6410f..81f1d3346 100644 --- a/examples/device/msc_dual_lun/src/msc_disk_dual.c +++ b/examples/device/msc_dual_lun/src/msc_disk_dual.c @@ -34,9 +34,13 @@ // Some MCU doesn't have enough 8KB SRAM to store the whole disk // We will use Flash as read-only disk with board that has // CFG_EXAMPLE_MSC_READONLY defined +#if defined(CFG_EXAMPLE_MSC_READONLY) || defined(CFG_EXAMPLE_MSC_DUAL_READONLY) + #define MSC_CONST const +#else + #define MSC_CONST +#endif -enum -{ +enum { DISK_BLOCK_NUM = 16, // 8KB is the smallest size that windows allow to mount DISK_BLOCK_SIZE = 512 }; @@ -51,10 +55,7 @@ If you find any bugs or get any questions, feel free to file an\r\n\ issue at github.com/hathach/tinyusb" -#ifdef CFG_EXAMPLE_MSC_READONLY -const -#endif -uint8_t msc_disk0[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = +MSC_CONST uint8_t msc_disk0[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = { //------------- Block0: Boot Sector -------------// // byte_per_sector = DISK_BLOCK_SIZE; fat12_sector_num_16 = DISK_BLOCK_NUM; @@ -132,10 +133,7 @@ uint8_t msc_disk0[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = If you find any bugs or get any questions, feel free to file an\r\n\ issue at github.com/hathach/tinyusb" -#ifdef CFG_EXAMPLE_MSC_READONLY -const -#endif -uint8_t msc_disk1[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = +MSC_CONST uint8_t msc_disk1[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = { //------------- Block0: Boot Sector -------------// // byte_per_sector = DISK_BLOCK_SIZE; fat12_sector_num_16 = DISK_BLOCK_NUM; @@ -206,15 +204,13 @@ uint8_t msc_disk1[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = }; // Invoked to determine max LUN -uint8_t tud_msc_get_maxlun_cb(void) -{ +uint8_t tud_msc_get_maxlun_cb(void) { return 2; // dual LUN } // Invoked when received SCSI_CMD_INQUIRY // Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively -void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) -{ +void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) { (void) lun; // use same ID for both LUNs const char vid[] = "TinyUSB"; @@ -228,8 +224,7 @@ void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16 // Invoked when received Test Unit Ready command. // return true allowing host to read/write this LUN e.g SD card inserted -bool tud_msc_test_unit_ready_cb(uint8_t lun) -{ +bool tud_msc_test_unit_ready_cb(uint8_t lun) { if ( lun == 1 && board_button_read() ) return false; return true; // RAM disk is always ready @@ -237,8 +232,7 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun) // Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size // Application update block count and block size -void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) -{ +void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) { (void) lun; *block_count = DISK_BLOCK_NUM; @@ -248,18 +242,14 @@ void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_siz // Invoked when received Start Stop Unit command // - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage // - Start = 1 : active mode, if load_eject = 1 : load disk storage -bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) -{ +bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) { (void) lun; (void) power_condition; - if ( load_eject ) - { - if (start) - { + if (load_eject) { + if (start) { // load disk storage - }else - { + } else { // unload disk storage } } @@ -269,10 +259,9 @@ bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, boo // Callback invoked when received READ10 command. // Copy disk's data to buffer (up to bufsize) and return number of copied bytes. -int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) -{ +int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) { // out of ramdisk - if ( lba >= DISK_BLOCK_NUM ) return -1; + if (lba >= DISK_BLOCK_NUM) return -1; uint8_t const* addr = (lun ? msc_disk1[lba] : msc_disk0[lba]) + offset; memcpy(buffer, addr, bufsize); @@ -280,11 +269,10 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff return (int32_t) bufsize; } -bool tud_msc_is_writable_cb (uint8_t lun) -{ +bool tud_msc_is_writable_cb(uint8_t lun) { (void) lun; -#ifdef CFG_EXAMPLE_MSC_READONLY +#if defined(CFG_EXAMPLE_MSC_READONLY) || defined(CFG_EXAMPLE_MSC_DUAL_READONLY) return false; #else return true; @@ -293,16 +281,18 @@ bool tud_msc_is_writable_cb (uint8_t lun) // Callback invoked when received WRITE10 command. // Process data in buffer to disk's storage and return number of written bytes -int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) -{ +int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) { // out of ramdisk - if ( lba >= DISK_BLOCK_NUM ) return -1; + if (lba >= DISK_BLOCK_NUM) return -1; -#ifndef CFG_EXAMPLE_MSC_READONLY +#if defined(CFG_EXAMPLE_MSC_READONLY) || defined(CFG_EXAMPLE_MSC_DUAL_READONLY) + (void) lun; + (void) lba; + (void) offset; + (void) buffer; +#else uint8_t* addr = (lun ? msc_disk1[lba] : msc_disk0[lba]) + offset; memcpy(addr, buffer, bufsize); -#else - (void) lun; (void) lba; (void) offset; (void) buffer; #endif return (int32_t) bufsize; @@ -311,8 +301,7 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* // Callback invoked when received an SCSI command not in built-in list below // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE // - READ10 and WRITE10 has their own callbacks -int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) -{ +int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) { // read10 & write10 has their own callback and MUST not be handled here void const* response = NULL; @@ -321,27 +310,23 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, // most scsi handled is input bool in_xfer = true; - switch (scsi_cmd[0]) - { + switch (scsi_cmd[0]) { default: // Set Sense = Invalid Command Operation tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // negative means error -> tinyusb could stall and/or response with failed status resplen = -1; - break; + break; } // return resplen must not larger than bufsize - if ( resplen > bufsize ) resplen = bufsize; + if (resplen > bufsize) resplen = bufsize; - if ( response && (resplen > 0) ) - { - if(in_xfer) - { + if (response && (resplen > 0)) { + if (in_xfer) { memcpy(buffer, response, (size_t) resplen); - }else - { + } else { // SCSI output } } diff --git a/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.cmake b/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.cmake new file mode 100644 index 000000000..8d3e0326e --- /dev/null +++ b/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.cmake @@ -0,0 +1,10 @@ +set(MCU_VARIANT D6) + +set(LD_FLASH_SIZE 64K) +set(LD_RAM_SIZE 20K) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + CFG_EXAMPLE_MSC_DUAL_READONLY + ) +endfunction() diff --git a/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h b/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h new file mode 100644 index 000000000..c8d28d90f --- /dev/null +++ b/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h @@ -0,0 +1,17 @@ +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define LED_PORT GPIOA +#define LED_PIN GPIO_Pin_15 +#define LED_STATE_ON 0 +#define LED_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.mk b/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.mk new file mode 100644 index 000000000..7d7462312 --- /dev/null +++ b/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.mk @@ -0,0 +1,7 @@ +MCU_VARIANT = D6 + +CFLAGS += -DCFG_EXAMPLE_MSC_DUAL_READONLY + +LDFLAGS += \ + -Wl,--defsym=__flash_size=64K \ + -Wl,--defsym=__ram_size=20K \ diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake index 2699f3e15..8d3e0326e 100644 --- a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake @@ -1,7 +1,10 @@ set(MCU_VARIANT D6) +set(LD_FLASH_SIZE 64K) +set(LD_RAM_SIZE 20K) + function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC - CH32V20x_D6 + CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk b/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk index 75dc05457..7d7462312 100644 --- a/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk @@ -1,5 +1,7 @@ -CFLAGS += \ - -DCH32V20x_D6 +MCU_VARIANT = D6 -SRC_S += \ - $(CH32V20X_SDK_SRC)/Startup/startup_ch32v20x_D6.S +CFLAGS += -DCFG_EXAMPLE_MSC_DUAL_READONLY + +LDFLAGS += \ + -Wl,--defsym=__flash_size=64K \ + -Wl,--defsym=__ram_size=20K \ diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake index fb39e3630..80b035fc0 100644 --- a/hw/bsp/ch32v20x/family.cmake +++ b/hw/bsp/ch32v20x/family.cmake @@ -1,7 +1,8 @@ include_guard() set(CH32_FAMILY ch32v20x) -set(SDK_DIR ${TOP}/hw/mcu/wch/${CH32_FAMILY}/EVT/EXAM/SRC) +set(SDK_DIR ${TOP}/hw/mcu/wch/${CH32_FAMILY}) +set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) @@ -23,29 +24,30 @@ function(add_board_target BOARD_TARGET) endif() if (NOT DEFINED LD_FILE_GNU) - set(LD_FILE_GNU ${SDK_DIR}/Ld/Link.ld) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${CH32_FAMILY}.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) - set(STARTUP_FILE_GNU ${SDK_DIR}/Startup/startup_${CH32_FAMILY}_${MCU_VARIANT}.S) + set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_${CH32_FAMILY}_${MCU_VARIANT}.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/Core/core_riscv.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c + ${SDK_SRC_DIR}/Core/core_riscv.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${BOARD_TARGET} PUBLIC - ${SDK_DIR}/Peripheral/inc + ${SDK_SRC_DIR}/Peripheral/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) target_compile_definitions(${BOARD_TARGET} PUBLIC + CH32V20x_${MCU_VARIANT} BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED ) @@ -57,6 +59,8 @@ function(add_board_target BOARD_TARGET) ) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" + -Wl,--defsym=__flash_size=${LD_FLASH_SIZE} + -Wl,--defsym=__ram_size=${LD_RAM_SIZE} -nostartfiles --specs=nosys.specs --specs=nano.specs ) diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index 7e290bb18..6b09fdac7 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -7,12 +7,9 @@ # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack CROSS_COMPILE ?= riscv-none-elf- -# Submodules -CH32V20X_SDK = hw/mcu/wch/ch32v20x -DEPS_SUBMODULES += $(CH32V20X_SDK) - -# WCH-SDK paths -CH32V20X_SDK_SRC = $(CH32V20X_SDK)/EVT/EXAM/SRC +CH32_FAMILY = ch32v20x +SDK_DIR = hw/mcu/wch/ch32v20x +SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 @@ -23,27 +20,29 @@ CFLAGS += \ -fdata-sections \ -ffat-lto-objects \ -flto \ + -DCH32V20x_${MCU_VARIANT} \ -DCFG_TUSB_MCU=OPT_MCU_CH32V20X \ -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED \ LDFLAGS_GCC += \ - -Wl,--gc-sections \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs \ -LD_FILE = $(CH32V20X_SDK_SRC)/Ld/Link.ld +LD_FILE = $(FAMILY_PATH)/linker/${CH32_FAMILY}.ld SRC_C += \ src/portable/wch/dcd_ch32_usbfs.c \ - $(CH32V20X_SDK_SRC)/Core/core_riscv.c \ - $(CH32V20X_SDK_SRC)/Peripheral/src/ch32v20x_gpio.c \ - $(CH32V20X_SDK_SRC)/Peripheral/src/ch32v20x_misc.c \ - $(CH32V20X_SDK_SRC)/Peripheral/src/ch32v20x_rcc.c \ - $(CH32V20X_SDK_SRC)/Peripheral/src/ch32v20x_usart.c \ + $(SDK_SRC_DIR)/Core/core_riscv.c \ + $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_gpio.c \ + $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_misc.c \ + $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_rcc.c \ + $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_usart.c \ + +SRC_S += $(SDK_SRC_DIR)/Startup/startup_ch32v20x_${MCU_VARIANT}.S INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/$(CH32V20X_SDK_SRC)/Peripheral/inc \ + $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc \ FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V diff --git a/hw/bsp/ch32v20x/linker/ch32v20x.ld b/hw/bsp/ch32v20x/linker/ch32v20x.ld new file mode 100644 index 000000000..6ee2fa1c7 --- /dev/null +++ b/hw/bsp/ch32v20x/linker/ch32v20x.ld @@ -0,0 +1 @@ +/* Define default values if not already defined */ __FLASH_SIZE = DEFINED(__flash_size) ? __flash_size : 64K; __RAM_SIZE = DEFINED(__ram_size) ? __ram_size : 20K; MEMORY { FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __FLASH_SIZE RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __RAM_SIZE } ENTRY( _start ) __stack_size = 2048; PROVIDE( _stack_size = __stack_size ); SECTIONS { .init : { _sinit = .; . = ALIGN(4); KEEP(*(SORT_NONE(.init))) . = ALIGN(4); _einit = .; } >FLASH AT>FLASH .vector : { *(.vector); . = ALIGN(64); } >FLASH AT>FLASH .text : { . = ALIGN(4); *(.text) *(.text.*) *(.rodata) *(.rodata*) *(.gnu.linkonce.t.*) . = ALIGN(4); } >FLASH AT>FLASH .fini : { KEEP(*(SORT_NONE(.fini))) . = ALIGN(4); } >FLASH AT>FLASH PROVIDE( _etext = . ); PROVIDE( _eitcm = . ); .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH AT>FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH AT>FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH AT>FLASH .ctors : { /* gcc uses crtbegin.o to find the start of the constructors, so we make sure it is first. Because this is a wildcard, it doesn't matter if the user does not actually link against crtbegin.o; the linker won't look for a file to match a wildcard. The wildcard also means that it doesn't matter which directory crtbegin.o is in. */ KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin?.o(.ctors)) /* We don't want to include the .ctor section from the crtend.o file until after the sorted ctors. The .ctor section from the crtend file contains the end of ctors marker and it must be last */ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) } >FLASH AT>FLASH .dtors : { KEEP (*crtbegin.o(.dtors)) KEEP (*crtbegin?.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) } >FLASH AT>FLASH .dalign : { . = ALIGN(4); PROVIDE(_data_vma = .); } >RAM AT>FLASH .dlalign : { . = ALIGN(4); PROVIDE(_data_lma = .); } >FLASH AT>FLASH .data : { *(.gnu.linkonce.r.*) *(.data .data.*) *(.gnu.linkonce.d.*) . = ALIGN(8); PROVIDE( __global_pointer$ = . + 0x800 ); *(.sdata .sdata.*) *(.sdata2.*) *(.gnu.linkonce.s.*) . = ALIGN(8); *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) . = ALIGN(4); PROVIDE( _edata = .); } >RAM AT>FLASH .bss : { . = ALIGN(4); PROVIDE( _sbss = .); *(.sbss*) *(.gnu.linkonce.sb.*) *(.bss*) *(.gnu.linkonce.b.*) *(COMMON*) . = ALIGN(4); PROVIDE( _ebss = .); } >RAM AT>FLASH PROVIDE( _end = _ebss); PROVIDE( end = . ); .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : { PROVIDE( _heap_end = . ); . = ALIGN(4); PROVIDE(_susrstack = . ); . = . + __stack_size; PROVIDE( _eusrstack = .); } >RAM } -- cgit v1.3.1 From b19295c1c15de676e7cebd5bd5b6aa53887c6a56 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 20 May 2024 17:26:04 +0700 Subject: use correct wch usbhs, usbfs for ch32v307 using CFG_TUD_MAX_SPEED --- examples/build_system/make/rules.mk | 11 ++++++ hw/bsp/ch32v20x/family.mk | 10 +---- hw/bsp/ch32v307/family.c | 77 ++++++++++++------------------------- hw/bsp/ch32v307/family.cmake | 27 +++++++------ hw/bsp/ch32v307/family.mk | 61 +++++++++++++---------------- src/common/tusb_mcu.h | 16 ++++++-- src/portable/wch/ch32_usbhs_reg.h | 4 +- src/portable/wch/dcd_ch32_usbfs.c | 3 +- src/portable/wch/dcd_ch32_usbhs.c | 6 +-- 9 files changed, 98 insertions(+), 117 deletions(-) diff --git a/examples/build_system/make/rules.mk b/examples/build_system/make/rules.mk index 7b6b339ed..102c6db0c 100644 --- a/examples/build_system/make/rules.mk +++ b/examples/build_system/make/rules.mk @@ -134,6 +134,17 @@ OPENOCD_OPTION ?= flash-openocd: $(BUILD)/$(PROJECT).elf openocd $(OPENOCD_OPTION) -c "program $< verify reset exit" +# --------------- openocd-wch ----------------- +# wch-linke is not supported yet in official openOCD yet. We need to either use +# 1. download openocd as part of mounriver studio http://www.mounriver.com/download or +# 2. compiled from https://github.com/hathach/riscv-openocd-wch or +# https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz +# with ./configure --disable-werror --enable-wlinke --enable-ch347=no +OPENOCD_WCH ?= /home/${USER}/app/riscv-openocd-wch/src/openocd +OPENOCD_WCH_OPTION ?= +flash-openocd-wch: $(BUILD)/$(PROJECT).elf + $(OPENOCD_WCH) $(OPENOCD_WCH_OPTION) -c init -c halt -c "flash write_image $<" -c reset -c exit + # --------------- dfu-util ----------------- DFU_UTIL_OPTION ?= -a 0 flash-dfu-util: $(BUILD)/$(PROJECT).bin diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index 6b09fdac7..5c8b31a1c 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -16,8 +16,6 @@ CPU_CORE ?= rv32imac-ilp32 CFLAGS += \ -mcmodel=medany \ - -ffunction-sections \ - -fdata-sections \ -ffat-lto-objects \ -flto \ -DCH32V20x_${MCU_VARIANT} \ @@ -46,9 +44,5 @@ INC += \ FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V -# wch-link is not supported yet in official openOCD yet. We need to either use -# 1. download openocd as part of mounriver studio http://www.mounriver.com/download or -# 2. compiled from modified source https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz -OPENOCD ?= $(HOME)/app/riscv-openocd-wch/src/openocd -flash: $(BUILD)/$(PROJECT).elf - $(OPENOCD) -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "flash write_image $<" -c reset -c exit +OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg +flash: flash-openocd-wch diff --git a/hw/bsp/ch32v307/family.c b/hw/bsp/ch32v307/family.c index 50e48e7df..fe37ea8e3 100644 --- a/hw/bsp/ch32v307/family.c +++ b/hw/bsp/ch32v307/family.c @@ -35,41 +35,31 @@ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USBHS_IRQHandler (void) __attribute__((naked)); -void USBHS_IRQHandler (void) -{ - __asm volatile ("call USBHS_IRQHandler_impl; mret"); -} +// TODO maybe having FS as port0, HS as port1 -__attribute__ ((used)) void USBHS_IRQHandler_impl (void) -{ +__attribute__((interrupt)) void USBHS_IRQHandler(void) { + #if CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED tud_int_handler(0); + #endif } - -void OTG_FS_IRQHandler (void) __attribute__((naked)); -void OTG_FS_IRQHandler (void) -{ - __asm volatile ("call OTG_FS_IRQHandler_impl; mret"); -} - -__attribute__ ((used)) void OTG_FS_IRQHandler_impl (void) -{ +__attribute__((interrupt)) void OTG_FS_IRQHandler(void) { + #if CFG_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED tud_int_handler(0); + #endif } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ -uint32_t SysTick_Config(uint32_t ticks) -{ +uint32_t SysTick_Config(uint32_t ticks) { NVIC_EnableIRQ(SysTicK_IRQn); - SysTick->CTLR=0; - SysTick->SR=0; - SysTick->CNT=0; - SysTick->CMP=ticks-1; - SysTick->CTLR=0xF; + SysTick->CTLR = 0; + SysTick->SR = 0; + SysTick->CNT = 0; + SysTick->CMP = ticks - 1; + SysTick->CTLR = 0xF; return 0; } @@ -82,17 +72,17 @@ void board_init(void) { SysTick_Config(SystemCoreClock / 1000); #endif - usart_printf_init(115200); + usart_printf_init(115200); - #if 0 +#if CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED + // Use Highspeed USB RCC_USBCLK48MConfig(RCC_USBCLK48MCLKSource_USBPHY); RCC_USBHSPLLCLKConfig(RCC_HSBHSPLLCLKSource_HSE); RCC_USBHSConfig(RCC_USBPLL_Div2); RCC_USBHSPLLCKREFCLKConfig(RCC_USBHSPLLCKREFCLK_4M); RCC_USBHSPHYPLLALIVEcmd(ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHS, ENABLE); - - #else +#else uint8_t otg_div; switch (SystemCoreClock) { case 48000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div1; break; @@ -102,7 +92,7 @@ void board_init(void) { } RCC_OTGFSCLKConfig(otg_div); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); - #endif +#endif GPIO_InitTypeDef GPIO_InitStructure = {0}; @@ -127,24 +117,14 @@ void board_init(void) { } #if CFG_TUSB_OS == OPT_OS_NONE - volatile uint32_t system_ticks = 0; -/* Small workaround to support HW stack save/restore */ -void SysTick_Handler (void) __attribute__((naked)); -void SysTick_Handler (void) -{ - __asm volatile ("call SysTick_Handler_impl; mret"); -} - -__attribute__((used)) void SysTick_Handler_impl (void) -{ +__attribute__((interrupt)) void SysTick_Handler(void) { SysTick->SR = 0; system_ticks++; } -uint32_t board_millis (void) -{ +uint32_t board_millis(void) { return system_ticks; } @@ -154,36 +134,29 @@ uint32_t board_millis (void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write (bool state) -{ +void board_led_write(bool state) { GPIO_WriteBit(LED_PORT, LED_PIN, state); } -uint32_t board_button_read (void) -{ +uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN); } -int board_uart_read (uint8_t *buf, int len) -{ +int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } -int board_uart_write (void const *buf, int len) -{ +int board_uart_write(void const* buf, int len) { int txsize = len; - while ( txsize-- ) - { + while (txsize--) { uart_write(*(uint8_t const*) buf); buf++; } return len; } - - #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake index 8a4bd7730..fd475c987 100644 --- a/hw/bsp/ch32v307/family.cmake +++ b/hw/bsp/ch32v307/family.cmake @@ -1,7 +1,8 @@ include_guard() set(CH32_FAMILY ch32v30x) -set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v307/EVT/EXAM/SRC) +set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v307) +set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) @@ -13,7 +14,10 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TO set(FAMILY_MCUS CH32V307 CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") -# Port0 Fullspeed, Port1 Highspeed +# default to highspeed +if (NOT DEFINED SPEED) + set(SPEED high) +endif() #------------------------------------ # BOARD_TARGET @@ -30,27 +34,26 @@ function(add_board_target BOARD_TARGET) set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) - set(STARTUP_FILE_GNU ${SDK_DIR}/Startup/startup_${CH32_FAMILY}_D8C.S) + set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_${CH32_FAMILY}_D8C.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/Core/core_riscv.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c + ${SDK_SRC_DIR}/Core/core_riscv.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${CH32_FAMILY}_it.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${BOARD_TARGET} PUBLIC - ${SDK_DIR}/Peripheral/inc + ${SDK_SRC_DIR}/Peripheral/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) target_compile_definitions(${BOARD_TARGET} PUBLIC - #BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED - BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + BOARD_TUD_MAX_SPEED=$,OPT_MODE_HIGH_SPEED,OPT_MODE_FULL_SPEED> ) update_board(${BOARD_TARGET}) @@ -104,7 +107,7 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_CH32V307 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC - #${TOP}/src/portable/wch/dcd_ch32_usbhs.c + ${TOP}/src/portable/wch/dcd_ch32_usbhs.c ${TOP}/src/portable/wch/dcd_ch32_usbfs.c ) target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index df9ded4a0..2dbe0c46a 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -7,63 +7,54 @@ # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack CROSS_COMPILE ?= riscv-none-elf- -# Submodules -CH32V307_SDK = hw/mcu/wch/ch32v307 - -# WCH-SDK paths -CH32V307_SDK_SRC = $(CH32V307_SDK)/EVT/EXAM/SRC +CH32_FAMILY = ch32v30x +SDK_DIR = hw/mcu/wch/ch32v307 +SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 +# default to use high speed port, unless specified in board.mk or command line +SPEED ?= high + CFLAGS += \ -flto \ -msmall-data-limit=8 \ - -mno-save-restore -Os \ + -mno-save-restore \ -fmessage-length=0 \ -fsigned-char \ - -ffunction-sections \ - -fdata-sections \ -DCFG_TUSB_MCU=OPT_MCU_CH32V307 \ - -Xlinker --gc-sections \ - -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + +ifeq ($(SPEED),high) + CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + $(info "Using USBHS driver for HighSpeed mode") +else + CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + $(info "Using USBFS driver for FullSpeed mode") +endif LDFLAGS_GCC += \ -nostdlib -nostartfiles \ - --specs=nosys.specs --specs=nano.specs + --specs=nosys.specs --specs=nano.specs \ SRC_C += \ src/portable/wch/dcd_ch32_usbhs.c \ - $(CH32V307_SDK_SRC)/Core/core_riscv.c \ - $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_gpio.c \ - $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_misc.c \ - $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_rcc.c \ - $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_usart.c + src/portable/wch/dcd_ch32_usbfs.c \ + $(SDK_SRC_DIR)/Core/core_riscv.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_misc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_rcc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_usart.c SRC_S += \ - $(CH32V307_SDK_SRC)/Startup/startup_ch32v30x_D8C.S + $(SDK_SRC_DIR)/Startup/startup_${CH32_FAMILY}_D8C.S INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/$(CH32V307_SDK_SRC)/Peripheral/inc + $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V -# wch-link is not supported yet in official openOCD yet. We need to either use -# 1. download openocd as part of mounriver studio http://www.mounriver.com/download or -# 2. compiled from modified source https://github.com/kprasadvnsi/riscv-openocd-wch -# -# Note: For Linux, somehow openocd in mounriver studio does not seem to have wch-link enable, -# therefore we need to compile it from source as follows: -# git clone https://github.com/kprasadvnsi/riscv-openocd-wch -# cd riscv-openocd-wch -# ./bootstrap -# ./configure CFLAGS="-Wno-error" --enable-wlink -# make -# openocd binaries will be generated in riscv-openocd-wch/src - -# flash target ROM bootloader -OPENOCD_WCH = /home/${USER}/app/riscv-openocd-wch/src/openocd -flash: $(BUILD)/$(PROJECT).elf - $(OPENOCD_WCH) -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "program $<" -c wlink_reset_resume -c exit +OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg +flash: flash-openocd-wch diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index e313fea05..d928e44e8 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -404,14 +404,22 @@ //------------- WCH -------------// #elif TU_CHECK_MCU(OPT_MCU_CH32V307) - #define TUP_DCD_ENDPOINT_MAX 8 -// #define TUP_RHPORT_HIGHSPEED 1 + // v307 support both FS and HS + #define TUP_USBIP_WCH_USBHS + #define TUP_USBIP_WCH_USBFS + + #define TUP_RHPORT_HIGHSPEED 1 // default to highspeed + #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED ? 16 : 8) #elif TU_CHECK_MCU(OPT_MCU_CH32F20X) - #define TUP_DCD_ENDPOINT_MAX 16 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_USBIP_WCH_USBHS + #define TUP_USBIP_WCH_USBFS + + #define TUP_RHPORT_HIGHSPEED 1 // default to highspeed + #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED ? 16 : 8) #elif TU_CHECK_MCU(OPT_MCU_CH32V20X) + #define TUP_USBIP_WCH_USBFS #define TUP_DCD_ENDPOINT_MAX 8 #endif diff --git a/src/portable/wch/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h index 9b956231f..6ae91ec71 100644 --- a/src/portable/wch/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -2,9 +2,9 @@ #define _USB_CH32_USBHS_REG_H #if (CFG_TUSB_MCU == OPT_MCU_CH32V307) -#include + #include #elif (CFG_TUSB_MCU == OPT_MCU_CH32F20X) -#include + #include #endif /******************* GLOBAL ******************/ diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 3e4b6cae5..413fe92c9 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -1,6 +1,7 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X || CFG_TUSB_MCU == OPT_MCU_CH32V307) +// Note: CH32 can have both USB FS and HS, only use this driver if CFG_TUD_MAX_SPEED is full speed +#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBFS) && (CFG_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED) #include #include "device/dcd.h" diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 68e2179e9..9a12fc97f 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -26,11 +26,11 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && ((CFG_TUSB_MCU == OPT_MCU_CH32V307) || (CFG_TUSB_MCU == OPT_MCU_CH32F20X)) -#include "device/dcd.h" - +// Note: CH32 can have both USB FS and HS, only use this driver if CFG_TUD_MAX_SPEED is high speed +#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBHS) && (CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED) #include "ch32_usbhs_reg.h" +#include "device/dcd.h" // Max number of bi-directional endpoints including EP0 #define EP_MAX 16 -- cgit v1.3.1 From 07d879378f052386699aba1eb41f04d4d32fb865 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 20 May 2024 17:32:40 +0700 Subject: code format add missing MIT license --- .idea/cmake.xml | 2 + src/portable/wch/ch32_usbfs_reg.h | 41 +++- src/portable/wch/ch32_usbhs_reg.h | 37 ++- src/portable/wch/dcd_ch32_usbfs.c | 482 ++++++++++++++++++++------------------ 4 files changed, 323 insertions(+), 239 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index a34f19e1f..d96b46853 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -132,6 +132,8 @@ + + \ No newline at end of file diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h index d5341f3a8..0a50a6169 100644 --- a/src/portable/wch/ch32_usbfs_reg.h +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -1,15 +1,42 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 Matthew Tran + * Copyright (c) 2024 hathach + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + #ifndef USB_CH32_USBFS_REG_H #define USB_CH32_USBFS_REG_H -#if (CFG_TUSB_MCU == OPT_MCU_CH32V307) -#include -#define USBHD_IRQn OTG_FS_IRQn +#if CFG_TUSB_MCU == OPT_MCU_CH32V307 + #include + #define USBHD_IRQn OTG_FS_IRQn -#elif (CFG_TUSB_MCU == OPT_MCU_CH32V20X) -#include +#elif CFG_TUSB_MCU == OPT_MCU_CH32V20X + #include -#elif (CFG_TUSB_MCU == OPT_MCU_CH32F20X) -#include +#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X + #include #endif // CTRL diff --git a/src/portable/wch/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h index 6ae91ec71..a3a41bb6a 100644 --- a/src/portable/wch/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -1,9 +1,36 @@ -#ifndef _USB_CH32_USBHS_REG_H -#define _USB_CH32_USBHS_REG_H - -#if (CFG_TUSB_MCU == OPT_MCU_CH32V307) +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 Matthew Tran + * Copyright (c) 2024 hathach + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef USB_CH32_USBHS_REG_H +#define USB_CH32_USBHS_REG_H + +#if CFG_TUSB_MCU == OPT_MCU_CH32V307 #include -#elif (CFG_TUSB_MCU == OPT_MCU_CH32F20X) +#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X #include #endif diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 413fe92c9..dafe4414e 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -1,9 +1,35 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 Matthew Tran + * Copyright (c) 2024 hathach + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + #include "tusb_option.h" // Note: CH32 can have both USB FS and HS, only use this driver if CFG_TUD_MAX_SPEED is full speed #if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBFS) && (CFG_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED) -#include #include "device/dcd.h" #include "ch32_usbfs_reg.h" @@ -17,301 +43,303 @@ /* private data */ struct usb_xfer { - bool valid; - uint8_t *buffer; - size_t len; - size_t processed_len; - size_t max_size; + bool valid; + uint8_t* buffer; + size_t len; + size_t processed_len; + size_t max_size; }; static struct { - bool ep0_tog; - bool isochronous[EP_MAX]; - struct usb_xfer xfer[EP_MAX][2]; - TU_ATTR_ALIGNED(4) uint8_t buffer[EP_MAX][2][64]; - TU_ATTR_ALIGNED(4) struct { - // OUT transfers >64 bytes will overwrite queued IN data! - uint8_t out[64]; - uint8_t in[1023]; - uint8_t pad; - } ep3_buffer; + bool ep0_tog; + bool isochronous[EP_MAX]; + struct usb_xfer xfer[EP_MAX][2]; + TU_ATTR_ALIGNED(4) uint8_t buffer[EP_MAX][2][64]; + TU_ATTR_ALIGNED(4) struct { + // OUT transfers >64 bytes will overwrite queued IN data! + uint8_t out[64]; + uint8_t in[1023]; + uint8_t pad; + } ep3_buffer; } data; /* private helpers */ static void update_in(uint8_t rhport, uint8_t ep, bool force) { - struct usb_xfer *xfer = &data.xfer[ep][TUSB_DIR_IN]; - if (xfer->valid) { - if (force || xfer->len) { - size_t len = TU_MIN(xfer->max_size, xfer->len); - if (ep == 0) { - memcpy(data.buffer[ep][TUSB_DIR_OUT], xfer->buffer, len); // ep0 uses same chunk - } else if (ep == 3) { - memcpy(data.ep3_buffer.in, xfer->buffer, len); - } else { - memcpy(data.buffer[ep][TUSB_DIR_IN], xfer->buffer, len); - } - xfer->buffer += len; - xfer->len -= len; - xfer->processed_len += len; - - EP_TX_LEN(ep) = len; - if (ep == 0) { - EP_TX_CTRL(0) = USBFS_EP_T_RES_ACK | (data.ep0_tog ? USBFS_EP_T_TOG : 0); - data.ep0_tog = !data.ep0_tog; - } else if (data.isochronous[ep]) { - EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NYET; - } else { - EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_ACK; - } - } else { - xfer->valid = false; - EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NAK; - dcd_event_xfer_complete(rhport, ep | TUSB_DIR_IN_MASK, xfer->processed_len, - XFER_RESULT_SUCCESS, true); - } + struct usb_xfer* xfer = &data.xfer[ep][TUSB_DIR_IN]; + if (xfer->valid) { + if (force || xfer->len) { + size_t len = TU_MIN(xfer->max_size, xfer->len); + if (ep == 0) { + memcpy(data.buffer[ep][TUSB_DIR_OUT], xfer->buffer, len); // ep0 uses same chunk + } else if (ep == 3) { + memcpy(data.ep3_buffer.in, xfer->buffer, len); + } else { + memcpy(data.buffer[ep][TUSB_DIR_IN], xfer->buffer, len); + } + xfer->buffer += len; + xfer->len -= len; + xfer->processed_len += len; + + EP_TX_LEN(ep) = len; + if (ep == 0) { + EP_TX_CTRL(0) = USBFS_EP_T_RES_ACK | (data.ep0_tog ? USBFS_EP_T_TOG : 0); + data.ep0_tog = !data.ep0_tog; + } else if (data.isochronous[ep]) { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NYET; + } else { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_ACK; + } + } else { + xfer->valid = false; + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NAK; + dcd_event_xfer_complete( + rhport, ep | TUSB_DIR_IN_MASK, xfer->processed_len, + XFER_RESULT_SUCCESS, true); } + } } static void update_out(uint8_t rhport, uint8_t ep, size_t rx_len) { - struct usb_xfer *xfer = &data.xfer[ep][TUSB_DIR_OUT]; - if (xfer->valid) { - size_t len = TU_MIN(xfer->max_size, TU_MIN(xfer->len, rx_len)); - if (ep == 3) { - memcpy(xfer->buffer, data.ep3_buffer.out, len); - } else { - memcpy(xfer->buffer, data.buffer[ep][TUSB_DIR_OUT], len); - } - xfer->buffer += len; - xfer->len -= len; - xfer->processed_len += len; - - if (xfer->len == 0 || len < xfer->max_size) { - xfer->valid = false; - dcd_event_xfer_complete(rhport, ep, xfer->processed_len, XFER_RESULT_SUCCESS, true); - } - - if (ep == 0) { - EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; - } + struct usb_xfer* xfer = &data.xfer[ep][TUSB_DIR_OUT]; + if (xfer->valid) { + size_t len = TU_MIN(xfer->max_size, TU_MIN(xfer->len, rx_len)); + if (ep == 3) { + memcpy(xfer->buffer, data.ep3_buffer.out, len); + } else { + memcpy(xfer->buffer, data.buffer[ep][TUSB_DIR_OUT], len); } -} + xfer->buffer += len; + xfer->len -= len; + xfer->processed_len += len; -/* public functions */ -void dcd_init(uint8_t rhport) { - // init registers - USBOTG_FS->BASE_CTRL = USBFS_CTRL_SYS_CTRL | USBFS_CTRL_INT_BUSY | USBFS_CTRL_DMA_EN; - USBOTG_FS->UDEV_CTRL = USBFS_UDEV_CTRL_PD_DIS | USBFS_UDEV_CTRL_PORT_EN; - USBOTG_FS->DEV_ADDR = 0x00; - - USBOTG_FS->INT_FG = 0xFF; - USBOTG_FS->INT_EN = USBFS_INT_EN_BUS_RST | USBFS_INT_EN_TRANSFER | USBFS_INT_EN_SUSPEND; - - // setup endpoint 0 - EP_DMA(0) = (uint32_t) &data.buffer[0][0]; - EP_TX_LEN(0) = 0; - EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; - EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + if (xfer->len == 0 || len < xfer->max_size) { + xfer->valid = false; + dcd_event_xfer_complete(rhport, ep, xfer->processed_len, XFER_RESULT_SUCCESS, true); + } - // enable other endpoints but NAK everything - USBOTG_FS->UEP4_1_MOD = 0xCC; - USBOTG_FS->UEP2_3_MOD = 0xCC; - USBOTG_FS->UEP5_6_MOD = 0xCC; - USBOTG_FS->UEP7_MOD = 0x0C; - - for (uint8_t ep = 1; ep < EP_MAX; ep++) { - EP_DMA(ep) = (uint32_t) &data.buffer[ep][0]; - EP_TX_LEN(ep) = 0; - EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; - EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NAK; + if (ep == 0) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; } - EP_DMA(3) = (uint32_t) &data.ep3_buffer.out[0]; + } +} - dcd_connect(rhport); +/* public functions */ +void dcd_init(uint8_t rhport) { + // init registers + USBOTG_FS->BASE_CTRL = USBFS_CTRL_SYS_CTRL | USBFS_CTRL_INT_BUSY | USBFS_CTRL_DMA_EN; + USBOTG_FS->UDEV_CTRL = USBFS_UDEV_CTRL_PD_DIS | USBFS_UDEV_CTRL_PORT_EN; + USBOTG_FS->DEV_ADDR = 0x00; + + USBOTG_FS->INT_FG = 0xFF; + USBOTG_FS->INT_EN = USBFS_INT_EN_BUS_RST | USBFS_INT_EN_TRANSFER | USBFS_INT_EN_SUSPEND; + + // setup endpoint 0 + EP_DMA(0) = (uint32_t) &data.buffer[0][0]; + EP_TX_LEN(0) = 0; + EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + + // enable other endpoints but NAK everything + USBOTG_FS->UEP4_1_MOD = 0xCC; + USBOTG_FS->UEP2_3_MOD = 0xCC; + USBOTG_FS->UEP5_6_MOD = 0xCC; + USBOTG_FS->UEP7_MOD = 0x0C; + + for (uint8_t ep = 1; ep < EP_MAX; ep++) { + EP_DMA(ep) = (uint32_t) &data.buffer[ep][0]; + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NAK; + } + EP_DMA(3) = (uint32_t) &data.ep3_buffer.out[0]; + + dcd_connect(rhport); } void dcd_int_handler(uint8_t rhport) { - (void) rhport; - uint8_t status = USBOTG_FS->INT_FG; - if (status & USBFS_INT_FG_TRANSFER) { - uint8_t ep = USBFS_INT_ST_MASK_UIS_ENDP(USBOTG_FS->INT_ST); - uint8_t token = USBFS_INT_ST_MASK_UIS_TOKEN(USBOTG_FS->INT_ST); - - switch (token) { - case PID_OUT: { - uint16_t rx_len = USBOTG_FS->RX_LEN; - update_out(rhport, ep, rx_len); - break; - } - - case PID_IN: - update_in(rhport, ep, false); - break; - - case PID_SETUP: - data.ep0_tog = true; - dcd_edpt_clear_stall(rhport, tu_edpt_addr(0, TUSB_DIR_IN)); // setup clears stall - dcd_edpt_clear_stall(rhport, tu_edpt_addr(0, TUSB_DIR_OUT)); - dcd_event_setup_received(rhport, &data.buffer[0][TUSB_DIR_OUT][0], true); - break; - } - - USBOTG_FS->INT_FG = USBFS_INT_FG_TRANSFER; - } else if (status & USBFS_INT_FG_BUS_RST) { + (void) rhport; + uint8_t status = USBOTG_FS->INT_FG; + if (status & USBFS_INT_FG_TRANSFER) { + uint8_t ep = USBFS_INT_ST_MASK_UIS_ENDP(USBOTG_FS->INT_ST); + uint8_t token = USBFS_INT_ST_MASK_UIS_TOKEN(USBOTG_FS->INT_ST); + + switch (token) { + case PID_OUT: { + uint16_t rx_len = USBOTG_FS->RX_LEN; + update_out(rhport, ep, rx_len); + break; + } + + case PID_IN: + update_in(rhport, ep, false); + break; + + case PID_SETUP: + // setup clears stall + EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + data.ep0_tog = true; - data.xfer[0][TUSB_DIR_OUT].max_size = 64; - data.xfer[0][TUSB_DIR_IN].max_size = 64; + dcd_event_setup_received(rhport, &data.buffer[0][TUSB_DIR_OUT][0], true); + break; + } - dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); + USBOTG_FS->INT_FG = USBFS_INT_FG_TRANSFER; + } else if (status & USBFS_INT_FG_BUS_RST) { + data.ep0_tog = true; + data.xfer[0][TUSB_DIR_OUT].max_size = 64; + data.xfer[0][TUSB_DIR_IN].max_size = 64; - USBOTG_FS->DEV_ADDR = 0x00; - EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); - USBOTG_FS->INT_FG = USBFS_INT_FG_BUS_RST; - } else if (status & USBFS_INT_FG_SUSPEND) { - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SUSPEND }; - dcd_event_handler(&event, true); - USBOTG_FS->INT_FG = USBFS_INT_FG_SUSPEND; - } + USBOTG_FS->DEV_ADDR = 0x00; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + + USBOTG_FS->INT_FG = USBFS_INT_FG_BUS_RST; + } else if (status & USBFS_INT_FG_SUSPEND) { + dcd_event_t event = {.rhport = rhport, .event_id = DCD_EVENT_SUSPEND}; + dcd_event_handler(&event, true); + USBOTG_FS->INT_FG = USBFS_INT_FG_SUSPEND; + } } void dcd_int_enable(uint8_t rhport) { - (void) rhport; - NVIC_EnableIRQ(USBHD_IRQn); + (void) rhport; + NVIC_EnableIRQ(USBHD_IRQn); } void dcd_int_disable(uint8_t rhport) { - (void) rhport; - NVIC_DisableIRQ(USBHD_IRQn); + (void) rhport; + NVIC_DisableIRQ(USBHD_IRQn); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { - (void) dev_addr; - dcd_edpt_xfer(rhport, 0x80, NULL, 0); // zlp status response + (void) dev_addr; + dcd_edpt_xfer(rhport, 0x80, NULL, 0); // zlp status response } void dcd_remote_wakeup(uint8_t rhport) { - (void) rhport; - // TODO optional + (void) rhport; + // TODO optional } void dcd_connect(uint8_t rhport) { - (void) rhport; - USBOTG_FS->BASE_CTRL |= USBFS_CTRL_DEV_PUEN; + (void) rhport; + USBOTG_FS->BASE_CTRL |= USBFS_CTRL_DEV_PUEN; } void dcd_disconnect(uint8_t rhport) { - (void) rhport; - USBOTG_FS->BASE_CTRL &= ~USBFS_CTRL_DEV_PUEN; + (void) rhport; + USBOTG_FS->BASE_CTRL &= ~USBFS_CTRL_DEV_PUEN; } -void dcd_sof_enable(uint8_t rhport, bool en) -{ +void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } -void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { - (void) rhport; - if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && - request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && - request->bRequest == TUSB_REQ_SET_ADDRESS) { - USBOTG_FS->DEV_ADDR = (uint8_t) request->wValue; - } - EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; - EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) { + (void) rhport; + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS) { + USBOTG_FS->DEV_ADDR = (uint8_t) request->wValue; + } + EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; } -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { - (void) rhport; - uint8_t ep = tu_edpt_number(desc_ep->bEndpointAddress); - uint8_t dir = tu_edpt_dir(desc_ep->bEndpointAddress); - TU_ASSERT(ep < EP_MAX); - - data.isochronous[ep] = desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS; - data.xfer[ep][dir].max_size = tu_edpt_packet_size(desc_ep); - - if (ep != 0) { - if (dir == TUSB_DIR_OUT) { - if (data.isochronous[ep]) { - EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NYET; - } else { - EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_ACK; - } - } else { - EP_TX_LEN(ep) = 0; - EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; - } +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) { + (void) rhport; + uint8_t ep = tu_edpt_number(desc_ep->bEndpointAddress); + uint8_t dir = tu_edpt_dir(desc_ep->bEndpointAddress); + TU_ASSERT(ep < EP_MAX); + + data.isochronous[ep] = desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS; + data.xfer[ep][dir].max_size = tu_edpt_packet_size(desc_ep); + + if (ep != 0) { + if (dir == TUSB_DIR_OUT) { + if (data.isochronous[ep]) { + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NYET; + } else { + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_ACK; + } + } else { + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; } - return true; + } + return true; } void dcd_edpt_close_all(uint8_t rhport) { - (void) rhport; - // TODO optional + (void) rhport; + // TODO optional } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - (void) ep_addr; - // TODO optional + (void) rhport; + (void) ep_addr; + // TODO optional } -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - (void) rhport; - uint8_t ep = tu_edpt_number(ep_addr); - uint8_t dir = tu_edpt_dir(ep_addr); - - struct usb_xfer *xfer = &data.xfer[ep][dir]; - dcd_int_disable(rhport); - xfer->valid = true; - xfer->buffer = buffer; - xfer->len = total_bytes; - xfer->processed_len = 0; - dcd_int_enable(rhport); - - if (dir == TUSB_DIR_IN) { - update_in(rhport, ep, true); - } - return true; +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + + struct usb_xfer* xfer = &data.xfer[ep][dir]; + dcd_int_disable(rhport); + xfer->valid = true; + xfer->buffer = buffer; + xfer->len = total_bytes; + xfer->processed_len = 0; + dcd_int_enable(rhport); + + if (dir == TUSB_DIR_IN) { + update_in(rhport, ep, true); + } + return true; } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - uint8_t ep = tu_edpt_number(ep_addr); - uint8_t dir = tu_edpt_dir(ep_addr); - if (ep == 0) { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(0) = USBFS_EP_R_RES_STALL; - } else { - EP_TX_LEN(0) = 0; - EP_TX_CTRL(0) = USBFS_EP_T_RES_STALL; - } + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + if (ep == 0) { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_STALL; } else { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~USBFS_EP_R_RES_MASK) | USBFS_EP_R_RES_STALL; - } else { - EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~USBFS_EP_T_RES_MASK) | USBFS_EP_T_RES_STALL; - } + EP_TX_LEN(0) = 0; + EP_TX_CTRL(0) = USBFS_EP_T_RES_STALL; } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~USBFS_EP_R_RES_MASK) | USBFS_EP_R_RES_STALL; + } else { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~USBFS_EP_T_RES_MASK) | USBFS_EP_T_RES_STALL; + } + } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - uint8_t ep = tu_edpt_number(ep_addr); - uint8_t dir = tu_edpt_dir(ep_addr); - if (ep == 0) { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; - } + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + if (ep == 0) { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~(USBFS_EP_R_RES_MASK | USBFS_EP_R_TOG)) | USBFS_EP_R_RES_ACK; } else { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~(USBFS_EP_R_RES_MASK | USBFS_EP_R_TOG)) | USBFS_EP_R_RES_ACK; - } else { - EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK | USBFS_EP_T_TOG)) | USBFS_EP_T_RES_NAK; - } + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK | USBFS_EP_T_TOG)) | USBFS_EP_T_RES_NAK; } + } } -#endif // CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X) +#endif -- cgit v1.3.1 From 3b144be37fc3e146e68f4182bf18a1b460afeba6 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 20 May 2024 18:05:45 +0700 Subject: try fixing codeql --- examples/device/msc_dual_lun/src/msc_disk_dual.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/examples/device/msc_dual_lun/src/msc_disk_dual.c b/examples/device/msc_dual_lun/src/msc_disk_dual.c index 81f1d3346..b44b77c6c 100644 --- a/examples/device/msc_dual_lun/src/msc_disk_dual.c +++ b/examples/device/msc_dual_lun/src/msc_disk_dual.c @@ -300,10 +300,8 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* // Callback invoked when received an SCSI command not in built-in list below // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE -// - READ10 and WRITE10 has their own callbacks +// - READ10 and WRITE10 has their own callbacks (MUST not be handled here) int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) { - // read10 & write10 has their own callback and MUST not be handled here - void const* response = NULL; int32_t resplen = 0; @@ -316,8 +314,7 @@ int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, u tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // negative means error -> tinyusb could stall and/or response with failed status - resplen = -1; - break; + return -1; } // return resplen must not larger than bufsize -- cgit v1.3.1 From 10b1e38404c044345e9ea0f3e5c678af94eb0f0a Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 20 May 2024 18:30:38 +0700 Subject: revert unrelated changes to video_device.c --- src/class/video/video_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 974289b69..4218835aa 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -609,7 +609,7 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); tusb_desc_cs_video_frm_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); - uint_fast32_t interval, interval_ms = 0; + uint_fast32_t interval, interval_ms; switch (request) { case VIDEO_REQUEST_GET_MAX: { uint_fast32_t min_interval, max_interval; -- cgit v1.3.1 From c2cfb71dce4d514ff79ec98af46984b543c6f49e Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 21 May 2024 12:11:08 +0700 Subject: circle ci remove deps caching to reduce storage credit --- .circleci/config.yml | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2d4532aee..5cbe3a171 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -44,30 +44,10 @@ commands: family: type: string steps: - - run: - name: Make deps cache key - command: | - python tools/get_deps.py --print > deps_key - - restore_cache: - name: Restore Dependencies Cache - key: deps-{{ checksum "deps_key" }} - paths: - - lib/CMSIS_5 - - lib/FreeRTOS-Kernel - - lib/lwip - - tools/uf2 - run: name: Get Dependencies command: | python tools/get_deps.py << parameters.family >> - - save_cache: - name: Save Dependencies Cache - key: deps-{{ checksum "deps_key" }} - paths: - - lib/CMSIS_5 - - lib/FreeRTOS-Kernel - - lib/lwip - - tools/uf2 jobs: arm-clang: -- cgit v1.3.1 From 4e24ec5e5d19f47748a13d5d4849a56c4ff7ba87 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 21 May 2024 12:49:57 +0700 Subject: circle ci skip cache for toolchain action skip cache for toolchain url hosted by github --- .circleci/config.yml | 26 +++++++++++----------- .../actions/setup_toolchain/download/action.yml | 3 ++- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5cbe3a171..7b36bed7c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,14 +8,14 @@ commands: toolchain_url: type: string steps: - - run: - name: Make toolchain cache key - command: echo "<< parameters.toolchain >>-<< parameters.toolchain_url>>" > toolchain_key - - restore_cache: - name: Restore Toolchain Cache - key: deps-{{ checksum "toolchain_key" }} - paths: - - ~/cache/<< parameters.toolchain >> +# - run: +# name: Make toolchain cache key +# command: echo "<< parameters.toolchain >>-<< parameters.toolchain_url>>" > toolchain_key +# - restore_cache: +# name: Restore Toolchain Cache +# key: deps-{{ checksum "toolchain_key" }} +# paths: +# - ~/cache/<< parameters.toolchain >> - run: name: Install Toolchain command: | @@ -25,11 +25,11 @@ commands: wget << parameters.toolchain_url>> -O toolchain.tar.gz tar -C ~/cache/<< parameters.toolchain >> -xaf toolchain.tar.gz fi - - save_cache: - name: Save Toolchain Cache - key: deps-{{ checksum "toolchain_key" }} - paths: - - ~/cache/<< parameters.toolchain >> +# - save_cache: +# name: Save Toolchain Cache +# key: deps-{{ checksum "toolchain_key" }} +# paths: +# - ~/cache/<< parameters.toolchain >> - run: name: Setup build environment command: | diff --git a/.github/actions/setup_toolchain/download/action.yml b/.github/actions/setup_toolchain/download/action.yml index 0b35bddb1..2af456ef8 100644 --- a/.github/actions/setup_toolchain/download/action.yml +++ b/.github/actions/setup_toolchain/download/action.yml @@ -12,6 +12,7 @@ runs: using: "composite" steps: - name: Cache Toolchain + if: ${{ !startsWith(inputs.toolchain_url, 'https://github.com') }} uses: actions/cache@v4 id: cache-toolchain-download with: @@ -22,7 +23,7 @@ runs: if: steps.cache-toolchain-download.outputs.cache-hit != 'true' run: | mkdir -p ~/cache/${{ inputs.toolchain }} - wget --progress=dot:mega ${{ inputs.toolchain_url }} -O toolchain.tar.gz + wget --progress=dot:giga ${{ inputs.toolchain_url }} -O toolchain.tar.gz tar -C ~/cache/${{ inputs.toolchain }} -xaf toolchain.tar.gz shell: bash -- cgit v1.3.1 From 1d7aeb3fb6b53e8b71e7aecc8e99af425f87d174 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 21 May 2024 13:25:15 +0700 Subject: try to update cache for esp-idf --- .github/actions/setup_toolchain/espressif/action.yml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/actions/setup_toolchain/espressif/action.yml b/.github/actions/setup_toolchain/espressif/action.yml index 494b7910e..46da02911 100644 --- a/.github/actions/setup_toolchain/espressif/action.yml +++ b/.github/actions/setup_toolchain/espressif/action.yml @@ -11,32 +11,31 @@ inputs: runs: using: "composite" steps: - - id: set-docker-image + - name: Set DOCKER_ESP_IDF run: | - DOCKER_IMAGE=$HOME/cache/${{ inputs.toolchain }}/docker_image.tar - echo "DOCKER_IMAGE=$DOCKER_IMAGE" >> $GITHUB_ENV - echo "DOCKER_IMAGE=$DOCKER_IMAGE" >> $GITHUB_OUTPUT + DOCKER_ESP_IDF=$HOME/cache/${{ inputs.toolchain }}/docker_image.tar + echo "DOCKER_ESP_IDF=$DOCKER_ESP_IDF" >> $GITHUB_ENV shell: bash - name: Cache Docker Image uses: actions/cache@v4 id: cache-toolchain-espressif with: - path: ${{ steps.set-docker-image.outputs.DOCKER_IMAGE }} + path: ${{ env.DOCKER_ESP_IDF }} key: ${{ inputs.toolchain }}-${{ inputs.toolchain_url }} - name: Pull and Save Docker Image if: steps.cache-toolchain-espressif.outputs.cache-hit != 'true' run: | docker pull espressif/idf:${{ inputs.toolchain_url }} - mkdir -p ~/cache/${{ inputs.toolchain }} - docker save -o $DOCKER_IMAGE espressif/idf:${{ inputs.toolchain_url }} - du -sh $DOCKER_IMAGE + mkdir -p $(dirname $DOCKER_ESP_IDF) + docker save -o $DOCKER_ESP_IDF espressif/idf:${{ inputs.toolchain_url }} + du -sh $DOCKER_ESP_IDF shell: bash - name: Load Docker Image if: steps.cache-toolchain-espressif.outputs.cache-hit == 'true' run: | - du -sh $DOCKER_IMAGE - docker load --input $DOCKER_IMAGE + du -sh $DOCKER_ESP_IDF + docker load --input $DOCKER_ESP_IDF shell: bash -- cgit v1.3.1 From 869e5e950c545459788cb67d9063f3489f5c5e54 Mon Sep 17 00:00:00 2001 From: dkrasutski Date: Sat, 30 Dec 2023 03:04:43 +0200 Subject: bugfix(ch32-hs-dcd): fix ch32 DATAx managment and long packet transmission --- src/portable/wch/ch32_usbhs_reg.h | 21 +-- src/portable/wch/dcd_ch32_usbhs.c | 379 ++++++++++++++++++-------------------- 2 files changed, 194 insertions(+), 206 deletions(-) diff --git a/src/portable/wch/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h index a3a41bb6a..7428285a5 100644 --- a/src/portable/wch/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -99,12 +99,16 @@ #define USBHS_ISO_ACT_FLAG (1 << 6) // INT_ST -#define USBHS_INT_ST_OFFSET 0x0B -#define USBHS_DEV_UIS_IS_NAK (1 << 7) -#define USBHS_DEV_UIS_TOG_OK (1 << 6) -#define MASK_UIS_TOKEN (3 << 4) -#define MASK_UIS_ENDP (0x0F) -#define MASK_UIS_H_RES (0x0F) +#define USBHS_INT_ST_OFFSET 0x0B +#define USBHS_DEV_UIS_IS_NAK (1 << 7) +#define USBHS_DEV_UIS_TOG_OK (1 << 6) +#define MASK_UIS_TOKEN (3 << 4) +#define USBHS_TOKEN_PID_OUT (0 << 4) +#define USBHS_TOKEN_PID_SOF (1 << 4) +#define USBHS_TOKEN_PID_IN (2 << 4) +#define USBHS_TOKEN_PID_SETUP (3 << 4) +#define MASK_UIS_ENDP (0x0F) +#define MASK_UIS_H_RES (0x0F) #define USBHS_TOGGLE_OK (0x40) #define USBHS_HOST_RES (0x0f) @@ -367,10 +371,5 @@ #define USBHS_UH_T_TOG_AUTO (1 << 5) #define USBHS_UH_T_DATA_NO (1 << 6) -// 00: OUT, 01:SOF, 10:IN, 11:SETUP -#define PID_OUT 0 -#define PID_SOF 1 -#define PID_IN 2 -#define PID_SETUP 3 #endif diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 9a12fc97f..0313c0a69 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2022 Greg Davill + * Copyright (c) 2023 Denis Krasutski * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,32 +34,99 @@ #include "device/dcd.h" // Max number of bi-directional endpoints including EP0 -#define EP_MAX 16 +#define EP_MAX 16 +#define CH32_USBHS_EP0_MAX_SIZE (64) typedef struct { uint8_t *buffer; - // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API uint16_t total_len; uint16_t queued_len; uint16_t max_size; - bool short_packet; + bool is_last_packet; } xfer_ctl_t; +typedef enum { + EP_RESPONSE_ACK, + EP_RESPONSE_NAK, +} ep_response_list_t; + #define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] static xfer_ctl_t xfer_status[EP_MAX][2]; -#define EP_TX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_TX_LEN) + (ep)*2) -#define EP_TX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_TX_CTRL) + (ep)*4) -#define EP_RX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_RX_CTRL) + (ep)*4) -#define EP_RX_MAX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_MAX_LEN) + (ep)*2) +#define EP_TX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_TX_LEN) + (ep) * 2) +#define EP_TX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_TX_CTRL) + (ep) * 4) +#define EP_RX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_RX_CTRL) + (ep) * 4) +#define EP_RX_MAX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_MAX_LEN) + (ep) * 2) #define EP_TX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_TX_DMA) + (ep - 1)) #define EP_RX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_RX_DMA) + (ep - 1)) /* Endpoint Buffer */ -TU_ATTR_ALIGNED(4) uint8_t EP0_DatabufHD[64]; // ep0(64) +TU_ATTR_ALIGNED(4) static uint8_t ep0_data_in_out_buffer[CH32_USBHS_EP0_MAX_SIZE]; + +static void ep_set_response_and_toggle(uint8_t ep_addr, ep_response_list_t response_type) { + uint8_t const ep_num = tu_edpt_number(ep_addr); + if (ep_addr & TUSB_DIR_IN_MASK) { + uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_T_RES_ACK : USBHS_EP_T_RES_NAK; + if (ep_num == 0) { + if (response_type == EP_RESPONSE_ACK) { + if (EP_TX_LEN(ep_num) == 0) { + EP_TX_CTRL(ep_num) |= USBHS_EP_T_TOG_1; + } else { + EP_TX_CTRL(ep_num) ^= USBHS_EP_T_TOG_1; + } + } + } + EP_TX_CTRL(ep_num) = (EP_TX_CTRL(ep_num) & ~(USBHS_EP_T_RES_MASK)) | response; + } else { + uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_R_RES_ACK : USBHS_EP_R_RES_NAK; + if (ep_num == 0) { + if (response_type == EP_RESPONSE_ACK) { + if (xfer_status[ep_num][TUSB_DIR_OUT].queued_len == 0) { + EP_RX_CTRL(ep_num) |= USBHS_EP_R_TOG_1; + } + } else { + EP_RX_CTRL(ep_num) ^= USBHS_EP_R_TOG_1; + } + } + EP_RX_CTRL(ep_num) = (EP_RX_CTRL(ep_num) & ~(USBHS_EP_R_RES_MASK)) | response; + } +} + +static void xfer_data_packet(uint8_t ep_addr, xfer_ctl_t *xfer) { + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); -volatile uint8_t USBHS_Dev_Endp0_Tog = 0x01; + if (dir == TUSB_DIR_IN) { + uint16_t remaining = xfer->total_len - xfer->queued_len; + uint16_t next_tx_size = TU_MIN(remaining, xfer->max_size); + + if (ep_num == 0) { + memcpy(ep0_data_in_out_buffer, &xfer->buffer[xfer->queued_len], next_tx_size); + } else { + EP_TX_DMA_ADDR(ep_num) = (uint32_t)&xfer->buffer[xfer->queued_len]; + } + + EP_TX_LEN(ep_num) = next_tx_size; + xfer->queued_len += next_tx_size; + if (xfer->queued_len == xfer->total_len) { + xfer->is_last_packet = true; + } + } else { /* TUSB_DIR_OUT */ + uint16_t left_to_receive = xfer->total_len - xfer->queued_len; + uint16_t max_possible_rx_size = TU_MIN(xfer->max_size, left_to_receive); + + if (max_possible_rx_size == left_to_receive) { + xfer->is_last_packet = true; + } + + if (ep_num > 0) { + EP_RX_DMA_ADDR(ep_num) = (uint32_t)&xfer->buffer[xfer->queued_len]; + EP_RX_MAX_LEN(ep_num) = max_possible_rx_size; + } + } + ep_set_response_and_toggle(ep_addr, USBHS_EP_R_RES_ACK); +} void dcd_init(uint8_t rhport) { (void)rhport; @@ -80,29 +148,23 @@ void dcd_init(uint8_t rhport) { USBHSD->INT_EN = 0; USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN; - /* ALL endpoint enable */ - USBHSD->ENDP_CONFIG = 0xffffffff; - USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; USBHSD->ENDP_TYPE = 0x00; USBHSD->BUF_MODE = 0x00; - USBHSD->UEP0_MAX_LEN = 64; - - USBHSD->UEP0_DMA = (uint32_t)EP0_DatabufHD; - - USBHSD->UEP0_TX_LEN = 0; - USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_NAK; - USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK; - - for (int ep = 1; ep < EP_MAX; ep++) { + for (int ep = 0; ep < EP_MAX; ep++) { EP_TX_LEN(ep) = 0; EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; - EP_RX_MAX_LEN(ep) = 512; + EP_RX_MAX_LEN(ep) = 0; } + USBHSD->UEP0_DMA = (uint32_t)ep0_data_in_out_buffer; + USBHSD->UEP0_MAX_LEN = CH32_USBHS_EP0_MAX_SIZE; + xfer_status[0][TUSB_DIR_OUT].max_size = CH32_USBHS_EP0_MAX_SIZE; + xfer_status[0][TUSB_DIR_IN].max_size = CH32_USBHS_EP0_MAX_SIZE; + USBHSD->DEV_AD = 0; USBHSD->CONTROL |= USBHS_DEV_PU_EN; } @@ -121,6 +183,16 @@ void dcd_int_disable(uint8_t rhport) { void dcd_edpt_close_all(uint8_t rhport) { (void)rhport; + + for (size_t ep = 1; ep < EP_MAX; ep++) { + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; + EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + + EP_RX_MAX_LEN(ep) = 0; + } + + USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { @@ -130,9 +202,8 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { dcd_edpt_xfer(rhport, 0x80, NULL, 0); } -void dcd_remote_wakeup(uint8_t rhport) -{ - (void) rhport; +void dcd_remote_wakeup(uint8_t rhport) { + (void)rhport; } void dcd_sof_enable(uint8_t rhport, bool en) @@ -154,246 +225,164 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *req USBHSD->DEV_AD = (uint8_t)request->wValue; } - EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK; - EP_RX_CTRL(0) = USBHS_EP_R_RES_ACK; + EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + EP_RX_CTRL(0) = USBHS_EP_R_RES_NAK | USBHS_EP_R_TOG_0; } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) { (void)rhport; - uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + uint8_t const ep_num = tu_edpt_number(desc_edpt->bEndpointAddress); + tusb_dir_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + + TU_ASSERT(ep_num < EP_MAX); - TU_ASSERT(epnum < EP_MAX); + if (ep_num == 0) { + return true; + } - xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, dir); + xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, dir); xfer->max_size = tu_edpt_packet_size(desc_edpt); - if (epnum != 0) { - if (tu_edpt_dir(desc_edpt->bEndpointAddress) == TUSB_DIR_OUT) { - EP_RX_CTRL(epnum) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK; - } else { - EP_TX_LEN(epnum) = 0; - EP_TX_CTRL(epnum) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + bool is_iso = (desc_edpt->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); + if (dir == TUSB_DIR_OUT) { + USBHSD->ENDP_CONFIG |= (USBHS_EP0_R_EN << ep_num); + EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + if (is_iso == true) { + USBHSD->ENDP_TYPE |= (USBHS_EP0_R_TYP << ep_num); + } + EP_RX_MAX_LEN(ep_num) = xfer->max_size; + } else { + USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); + if (is_iso == true) { + USBHSD->ENDP_TYPE |= (USBHS_EP0_T_TYP << ep_num); } + EP_TX_LEN(ep_num) = 0; + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; } return true; } -int usbd_ep_close(const uint8_t ep) { - (void)ep; +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void)rhport; - return 0; + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); + + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + EP_RX_MAX_LEN(ep_num) = 0; + USBHSD->ENDP_TYPE &= ~(USBHS_EP0_R_TYP << ep_num); + USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_R_EN << ep_num); + } else { // TUSB_DIR_IN + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + EP_TX_LEN(ep_num) = 0; + USBHSD->ENDP_TYPE &= ~(USBHS_EP0_T_TYP << ep_num); + USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); + } } + void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); - if (epnum == 0) { - if (dir == TUSB_DIR_OUT) { - USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_STALL; - } else { - USBHSD->UEP0_TX_LEN = 0; - USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_STALL; - } + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep_num) = USBHS_EP_R_RES_STALL; } else { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(epnum) = (EP_RX_CTRL(epnum) & ~USBHS_EP_R_RES_MASK) | USBHS_EP_R_RES_STALL; - - } else { - EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~USBHS_EP_T_RES_MASK) | USBHS_EP_T_RES_STALL; - } + EP_TX_LEN(0) = 0; + EP_TX_CTRL(ep_num) = USBHS_EP_T_RES_STALL; } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); - if (epnum == 0) { - if (dir == TUSB_DIR_OUT) { - USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK; - } else { - } + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; } else { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(epnum) = (EP_RX_CTRL(epnum) & ~(USBHS_EP_R_RES_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_T_RES_ACK; - - } else { - EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~(USBHS_EP_T_RES_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_T_RES_NAK; - } + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_R_RES_NAK; } } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { (void)rhport; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); - xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, dir); + xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, dir); xfer->buffer = buffer; - // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API xfer->total_len = total_bytes; xfer->queued_len = 0; - xfer->short_packet = false; - - // uint16_t num_packets = (total_bytes / xfer->max_size); - uint16_t short_packet_size = total_bytes % (xfer->max_size + 1); - - // Zero-size packet is special case. - if (short_packet_size == 0 || (total_bytes == 0)) { - xfer->short_packet = true; - } - - if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { - if (!total_bytes) { - xfer->short_packet = true; - if (epnum == 0) { - USBHSD->UEP0_TX_LEN = 0; - USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_ACK | (USBHS_Dev_Endp0_Tog ? USBHS_EP_T_TOG_1 : USBHS_EP_T_TOG_0); - USBHS_Dev_Endp0_Tog ^= 1; - } else { - EP_TX_LEN(epnum) = 0; - EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~(USBHS_EP_T_RES_MASK)) | USBHS_EP_T_RES_ACK; - } - } else { - if (epnum == 0) { - xfer->queued_len += short_packet_size; - memcpy(&EP0_DatabufHD[0], buffer, short_packet_size); - - USBHSD->UEP0_TX_LEN = short_packet_size; - USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_ACK | (USBHS_Dev_Endp0_Tog ? USBHS_EP_T_TOG_1 : USBHS_EP_T_TOG_0); - USBHS_Dev_Endp0_Tog ^= 1; - } else { - xfer->queued_len += short_packet_size; - - EP_TX_DMA_ADDR(epnum) = (uint32_t)buffer; - USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << epnum); - EP_TX_LEN(epnum) = short_packet_size; - EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~(USBHS_EP_T_RES_MASK)) | USBHS_EP_T_RES_ACK; - } - } - } else { /* TUSB_DIR_OUT */ - if (epnum == 0) { - uint32_t read_count = USBHSD->RX_LEN; - read_count = TU_MIN(read_count, total_bytes); + xfer->is_last_packet = false; - if ((total_bytes == 8)) { - read_count = 8; - memcpy(buffer, &EP0_DatabufHD[0], 8); - } else { - memcpy(buffer, &EP0_DatabufHD[0], read_count); - } - } else { - EP_RX_DMA_ADDR(epnum) = (uint32_t)xfer->buffer; - USBHSD->ENDP_CONFIG |= (USBHS_EP0_R_EN << epnum); - } + xfer_data_packet(ep_addr, xfer); - // usbd_ep_read(ep_addr, buffer, total_bytes, &ret_bytes); - } return true; } - -static void receive_packet(xfer_ctl_t *xfer, uint16_t xfer_size) { - // xfer->queued_len = xfer->total_len - remaining; - - uint16_t remaining = xfer->total_len - xfer->queued_len; - uint16_t to_recv_size; - - if (remaining <= xfer->max_size) { - // Avoid buffer overflow. - to_recv_size = (xfer_size > remaining) ? remaining : xfer_size; - } else { - // Room for full packet, choose recv_size based on what the microcontroller - // claims. - to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size; - } - - if (to_recv_size) { - } - - xfer->queued_len += xfer_size; - - // Per USB spec, a short OUT packet (including length 0) is always - // indicative of the end of a transfer (at least for ctl, bulk, int). - xfer->short_packet = (xfer_size < xfer->max_size); -} - void dcd_int_handler(uint8_t rhport) { (void)rhport; - uint32_t end_num, rx_token; - uint8_t intflag = 0; - - intflag = USBHSD->INT_FG; - - if (intflag & USBHS_TRANSFER_FLAG) { + uint8_t int_flag = USBHSD->INT_FG; + uint8_t int_status = USBHSD->INT_ST; - end_num = (USBHSD->INT_ST) & MASK_UIS_ENDP; - rx_token = (((USBHSD->INT_ST) & MASK_UIS_TOKEN) >> 4) & 0x03; + if (int_flag & USBHS_TRANSFER_FLAG) { - uint8_t endp = end_num | (rx_token == PID_IN ? TUSB_DIR_IN_MASK : 0); + uint8_t ep_num = int_status & MASK_UIS_ENDP; + uint8_t rx_token = int_status & MASK_UIS_TOKEN; - xfer_ctl_t *xfer = XFER_CTL_BASE(end_num, tu_edpt_dir(endp)); + uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; - if (rx_token == PID_SOF) { - dcd_event_sof(rhport, USBHSD->FRAME_NO, true); + xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); - } else if (rx_token == PID_OUT) { + if (rx_token == USBHS_TOKEN_PID_OUT) { uint16_t rx_len = USBHSD->RX_LEN; - receive_packet(xfer, rx_len); - - if (xfer->short_packet || (xfer->queued_len == xfer->total_len)) { - xfer->short_packet = false; - - dcd_event_xfer_complete(0, endp, xfer->queued_len, XFER_RESULT_SUCCESS, true); + if (ep_num == 0) { + memcpy(&xfer->buffer[xfer->queued_len], ep0_data_in_out_buffer, rx_len); } - if (end_num == 0) { - USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; + xfer->queued_len += rx_len; + if (rx_len < xfer->max_size) { + xfer->is_last_packet = true; } - } else if (rx_token == PID_IN) { - if (xfer->short_packet || (xfer->queued_len == xfer->total_len)) { - xfer->short_packet = false; - xfer->total_len = 0; - dcd_event_xfer_complete(0, endp, xfer->queued_len, XFER_RESULT_SUCCESS, true); - - EP_TX_CTRL(end_num) = (EP_TX_CTRL(end_num) & ~(USBHS_EP_T_RES_MASK)) | USBHS_EP_T_RES_NAK; + } else if (rx_token == USBHS_TOKEN_PID_IN) { + // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet + // Common processing below + } - if (end_num == 0) { - } - } else { - dcd_edpt_xfer(0, endp, xfer->buffer + xfer->queued_len, xfer->total_len - xfer->queued_len); - } + if (xfer->is_last_packet == true) { + ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); + dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } else { + /* prepare next part of packet to xref */ + xfer_data_packet(ep_addr, xfer); } USBHSD->INT_FG = USBHS_TRANSFER_FLAG; /* Clear flag */ - } else if (intflag & USBHS_SETUP_FLAG) { - USBHS_Dev_Endp0_Tog = 1; - dcd_event_setup_received(0, EP0_DatabufHD, true); + } else if (int_flag & USBHS_SETUP_FLAG) { + ep_set_response_and_toggle(0x80, EP_RESPONSE_NAK); + ep_set_response_and_toggle(0x00, EP_RESPONSE_NAK); + dcd_event_setup_received(0, ep0_data_in_out_buffer, true); USBHSD->INT_FG = USBHS_SETUP_FLAG; /* Clear flag */ - } else if (intflag & USBHS_DETECT_FLAG) { - USBHS_Dev_Endp0_Tog = 1; - - xfer_status[0][TUSB_DIR_OUT].max_size = 64; - xfer_status[0][TUSB_DIR_IN].max_size = 64; + } else if (int_flag & USBHS_DETECT_FLAG) { dcd_event_bus_reset(0, TUSB_SPEED_HIGH, true); USBHSD->DEV_AD = 0; - USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; + EP_RX_CTRL(0) = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; + EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; USBHSD->INT_FG = USBHS_DETECT_FLAG; /* Clear flag */ - } else if (intflag & USBHS_SUSPEND_FLAG) { + } else if (int_flag & USBHS_SUSPEND_FLAG) { dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SUSPEND }; dcd_event_handler(&event, true); -- cgit v1.3.1 From 3e604d1d5498cace44179026fe3ca017920704fe Mon Sep 17 00:00:00 2001 From: Denis Krasutski Date: Thu, 4 Jan 2024 12:22:11 +0200 Subject: fix(ch32, iso): fix iso IN transfers for CH32 --- src/portable/wch/dcd_ch32_usbhs.c | 76 +++++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 0313c0a69..42b15bf06 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -43,6 +43,7 @@ typedef struct { uint16_t queued_len; uint16_t max_size; bool is_last_packet; + bool is_iso; } xfer_ctl_t; typedef enum { @@ -77,7 +78,11 @@ static void ep_set_response_and_toggle(uint8_t ep_addr, ep_response_list_t respo } } } - EP_TX_CTRL(ep_num) = (EP_TX_CTRL(ep_num) & ~(USBHS_EP_T_RES_MASK)) | response; + if (xfer_status[ep_num][TUSB_DIR_IN].is_iso == true) { + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG; + } else { + EP_TX_CTRL(ep_num) = (EP_TX_CTRL(ep_num) & ~(USBHS_EP_T_RES_MASK)) | response; + } } else { uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_R_RES_ACK : USBHS_EP_R_RES_NAK; if (ep_num == 0) { @@ -112,6 +117,10 @@ static void xfer_data_packet(uint8_t ep_addr, xfer_ctl_t *xfer) { if (xfer->queued_len == xfer->total_len) { xfer->is_last_packet = true; } + if (xfer->is_iso == true) { + /* Enable EP to generate ISA_ACT interrupt */ + USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); + } } else { /* TUSB_DIR_OUT */ uint16_t left_to_receive = xfer->total_len - xfer->queued_len; uint16_t max_possible_rx_size = TU_MIN(xfer->max_size, left_to_receive); @@ -146,7 +155,7 @@ void dcd_init(uint8_t rhport) { #endif USBHSD->INT_EN = 0; - USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN; + USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN | USBHS_ISO_ACT_EN; USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; USBHSD->ENDP_TYPE = 0x00; @@ -244,18 +253,20 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) { xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, dir); xfer->max_size = tu_edpt_packet_size(desc_edpt); - bool is_iso = (desc_edpt->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); + xfer->is_iso = (desc_edpt->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); if (dir == TUSB_DIR_OUT) { USBHSD->ENDP_CONFIG |= (USBHS_EP0_R_EN << ep_num); EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; - if (is_iso == true) { + if (xfer->is_iso == true) { USBHSD->ENDP_TYPE |= (USBHS_EP0_R_TYP << ep_num); } EP_RX_MAX_LEN(ep_num) = xfer->max_size; } else { - USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); - if (is_iso == true) { + if (xfer->is_iso == true) { USBHSD->ENDP_TYPE |= (USBHS_EP0_T_TYP << ep_num); + } else { + /* Enable all types except Isochronous to avoid ISO_ACT interrupt generation */ + USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); } EP_TX_LEN(ep_num) = 0; EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; @@ -275,7 +286,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { EP_RX_MAX_LEN(ep_num) = 0; USBHSD->ENDP_TYPE &= ~(USBHS_EP0_R_TYP << ep_num); USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_R_EN << ep_num); - } else { // TUSB_DIR_IN + } else { // TUSB_DIR_IN EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; EP_TX_LEN(ep_num) = 0; USBHSD->ENDP_TYPE &= ~(USBHS_EP0_T_TYP << ep_num); @@ -332,30 +343,24 @@ void dcd_int_handler(uint8_t rhport) { uint8_t int_flag = USBHSD->INT_FG; uint8_t int_status = USBHSD->INT_ST; - if (int_flag & USBHS_TRANSFER_FLAG) { - + if (int_flag & USBHS_ISO_ACT_FLAG) { uint8_t ep_num = int_status & MASK_UIS_ENDP; uint8_t rx_token = int_status & MASK_UIS_TOKEN; - uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; - xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); if (rx_token == USBHS_TOKEN_PID_OUT) { uint16_t rx_len = USBHSD->RX_LEN; - if (ep_num == 0) { - memcpy(&xfer->buffer[xfer->queued_len], ep0_data_in_out_buffer, rx_len); - } - xfer->queued_len += rx_len; if (rx_len < xfer->max_size) { xfer->is_last_packet = true; } - } else if (rx_token == USBHS_TOKEN_PID_IN) { - // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet - // Common processing below + if (xfer->is_last_packet == true) { + /* Disable EP to avoid ISO_ACT interrupt generation */ + USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); + } } if (xfer->is_last_packet == true) { @@ -366,6 +371,41 @@ void dcd_int_handler(uint8_t rhport) { xfer_data_packet(ep_addr, xfer); } + USBHSD->INT_FG = USBHS_ISO_ACT_FLAG; /* Clear flag */ + } else if (int_flag & USBHS_TRANSFER_FLAG) { + + uint8_t ep_num = int_status & MASK_UIS_ENDP; + uint8_t rx_token = int_status & MASK_UIS_TOKEN; + uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; + xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); + + if (xfer->is_iso == false) { + if (rx_token == USBHS_TOKEN_PID_OUT) { + uint16_t rx_len = USBHSD->RX_LEN; + + if (ep_num == 0) { + memcpy(&xfer->buffer[xfer->queued_len], ep0_data_in_out_buffer, rx_len); + } + + xfer->queued_len += rx_len; + if (rx_len < xfer->max_size) { + xfer->is_last_packet = true; + } + + } else if (rx_token == USBHS_TOKEN_PID_IN) { + // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet + // Common processing below + } + + if (xfer->is_last_packet == true) { + ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); + dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } else { + /* prepare next part of packet to xref */ + xfer_data_packet(ep_addr, xfer); + } + } + USBHSD->INT_FG = USBHS_TRANSFER_FLAG; /* Clear flag */ } else if (int_flag & USBHS_SETUP_FLAG) { ep_set_response_and_toggle(0x80, EP_RESPONSE_NAK); -- cgit v1.3.1 From 4bd72da5cdce4b3ab8f5a9960234a97934672f1c Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 21 May 2024 15:41:59 +0700 Subject: use CFG_TUD_ENDPOINT0_SIZE, rename ep0_data_in_out_buffer to simply ep0_buffer reformat indent to 2 spaces --- src/portable/wch/dcd_ch32_usbhs.c | 552 +++++++++++++++++++------------------- 1 file changed, 274 insertions(+), 278 deletions(-) diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 42b15bf06..dbcf19a7b 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -34,21 +34,20 @@ #include "device/dcd.h" // Max number of bi-directional endpoints including EP0 -#define EP_MAX 16 -#define CH32_USBHS_EP0_MAX_SIZE (64) +#define EP_MAX 16 typedef struct { - uint8_t *buffer; - uint16_t total_len; - uint16_t queued_len; - uint16_t max_size; - bool is_last_packet; - bool is_iso; + uint8_t* buffer; + uint16_t total_len; + uint16_t queued_len; + uint16_t max_size; + bool is_last_packet; + bool is_iso; } xfer_ctl_t; typedef enum { - EP_RESPONSE_ACK, - EP_RESPONSE_NAK, + EP_RESPONSE_ACK, + EP_RESPONSE_NAK, } ep_response_list_t; #define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] @@ -63,371 +62,368 @@ static xfer_ctl_t xfer_status[EP_MAX][2]; #define EP_RX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_RX_DMA) + (ep - 1)) /* Endpoint Buffer */ -TU_ATTR_ALIGNED(4) static uint8_t ep0_data_in_out_buffer[CH32_USBHS_EP0_MAX_SIZE]; +TU_ATTR_ALIGNED(4) static uint8_t ep0_buffer[CFG_TUD_ENDPOINT0_SIZE]; static void ep_set_response_and_toggle(uint8_t ep_addr, ep_response_list_t response_type) { - uint8_t const ep_num = tu_edpt_number(ep_addr); - if (ep_addr & TUSB_DIR_IN_MASK) { - uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_T_RES_ACK : USBHS_EP_T_RES_NAK; - if (ep_num == 0) { - if (response_type == EP_RESPONSE_ACK) { - if (EP_TX_LEN(ep_num) == 0) { - EP_TX_CTRL(ep_num) |= USBHS_EP_T_TOG_1; - } else { - EP_TX_CTRL(ep_num) ^= USBHS_EP_T_TOG_1; - } - } - } - if (xfer_status[ep_num][TUSB_DIR_IN].is_iso == true) { - EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG; + uint8_t const ep_num = tu_edpt_number(ep_addr); + if (ep_addr & TUSB_DIR_IN_MASK) { + uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_T_RES_ACK : USBHS_EP_T_RES_NAK; + if (ep_num == 0) { + if (response_type == EP_RESPONSE_ACK) { + if (EP_TX_LEN(ep_num) == 0) { + EP_TX_CTRL(ep_num) |= USBHS_EP_T_TOG_1; } else { - EP_TX_CTRL(ep_num) = (EP_TX_CTRL(ep_num) & ~(USBHS_EP_T_RES_MASK)) | response; + EP_TX_CTRL(ep_num) ^= USBHS_EP_T_TOG_1; } + } + } + if (xfer_status[ep_num][TUSB_DIR_IN].is_iso == true) { + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG; } else { - uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_R_RES_ACK : USBHS_EP_R_RES_NAK; - if (ep_num == 0) { - if (response_type == EP_RESPONSE_ACK) { - if (xfer_status[ep_num][TUSB_DIR_OUT].queued_len == 0) { - EP_RX_CTRL(ep_num) |= USBHS_EP_R_TOG_1; - } - } else { - EP_RX_CTRL(ep_num) ^= USBHS_EP_R_TOG_1; - } + EP_TX_CTRL(ep_num) = (EP_TX_CTRL(ep_num) & ~(USBHS_EP_T_RES_MASK)) | response; + } + } else { + uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_R_RES_ACK : USBHS_EP_R_RES_NAK; + if (ep_num == 0) { + if (response_type == EP_RESPONSE_ACK) { + if (xfer_status[ep_num][TUSB_DIR_OUT].queued_len == 0) { + EP_RX_CTRL(ep_num) |= USBHS_EP_R_TOG_1; } - EP_RX_CTRL(ep_num) = (EP_RX_CTRL(ep_num) & ~(USBHS_EP_R_RES_MASK)) | response; + } else { + EP_RX_CTRL(ep_num) ^= USBHS_EP_R_TOG_1; + } } + EP_RX_CTRL(ep_num) = (EP_RX_CTRL(ep_num) & ~(USBHS_EP_R_RES_MASK)) | response; + } } -static void xfer_data_packet(uint8_t ep_addr, xfer_ctl_t *xfer) { - uint8_t const ep_num = tu_edpt_number(ep_addr); - tusb_dir_t const dir = tu_edpt_dir(ep_addr); +static void xfer_data_packet(uint8_t ep_addr, xfer_ctl_t* xfer) { + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); - if (dir == TUSB_DIR_IN) { - uint16_t remaining = xfer->total_len - xfer->queued_len; - uint16_t next_tx_size = TU_MIN(remaining, xfer->max_size); + if (dir == TUSB_DIR_IN) { + uint16_t remaining = xfer->total_len - xfer->queued_len; + uint16_t next_tx_size = TU_MIN(remaining, xfer->max_size); - if (ep_num == 0) { - memcpy(ep0_data_in_out_buffer, &xfer->buffer[xfer->queued_len], next_tx_size); - } else { - EP_TX_DMA_ADDR(ep_num) = (uint32_t)&xfer->buffer[xfer->queued_len]; - } + if (ep_num == 0) { + memcpy(ep0_buffer, &xfer->buffer[xfer->queued_len], next_tx_size); + } else { + EP_TX_DMA_ADDR(ep_num) = (uint32_t) &xfer->buffer[xfer->queued_len]; + } - EP_TX_LEN(ep_num) = next_tx_size; - xfer->queued_len += next_tx_size; - if (xfer->queued_len == xfer->total_len) { - xfer->is_last_packet = true; - } - if (xfer->is_iso == true) { - /* Enable EP to generate ISA_ACT interrupt */ - USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); - } - } else { /* TUSB_DIR_OUT */ - uint16_t left_to_receive = xfer->total_len - xfer->queued_len; - uint16_t max_possible_rx_size = TU_MIN(xfer->max_size, left_to_receive); + EP_TX_LEN(ep_num) = next_tx_size; + xfer->queued_len += next_tx_size; + if (xfer->queued_len == xfer->total_len) { + xfer->is_last_packet = true; + } + if (xfer->is_iso == true) { + /* Enable EP to generate ISA_ACT interrupt */ + USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); + } + } else { /* TUSB_DIR_OUT */ + uint16_t left_to_receive = xfer->total_len - xfer->queued_len; + uint16_t max_possible_rx_size = TU_MIN(xfer->max_size, left_to_receive); - if (max_possible_rx_size == left_to_receive) { - xfer->is_last_packet = true; - } + if (max_possible_rx_size == left_to_receive) { + xfer->is_last_packet = true; + } - if (ep_num > 0) { - EP_RX_DMA_ADDR(ep_num) = (uint32_t)&xfer->buffer[xfer->queued_len]; - EP_RX_MAX_LEN(ep_num) = max_possible_rx_size; - } + if (ep_num > 0) { + EP_RX_DMA_ADDR(ep_num) = (uint32_t) &xfer->buffer[xfer->queued_len]; + EP_RX_MAX_LEN(ep_num) = max_possible_rx_size; } - ep_set_response_and_toggle(ep_addr, USBHS_EP_R_RES_ACK); + } + ep_set_response_and_toggle(ep_addr, USBHS_EP_R_RES_ACK); } void dcd_init(uint8_t rhport) { - (void)rhport; + (void) rhport; - memset(&xfer_status, 0, sizeof(xfer_status)); + memset(&xfer_status, 0, sizeof(xfer_status)); - USBHSD->HOST_CTRL = 0x00; - USBHSD->HOST_CTRL = USBHS_PHY_SUSPENDM; + USBHSD->HOST_CTRL = 0x00; + USBHSD->HOST_CTRL = USBHS_PHY_SUSPENDM; - USBHSD->CONTROL = 0; + USBHSD->CONTROL = 0; #if TUD_OPT_HIGH_SPEED - USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_HIGH_SPEED; + USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_HIGH_SPEED; #else - #error OPT_MODE_FULL_SPEED not currently supported on CH32 - USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_FULL_SPEED; + #error OPT_MODE_FULL_SPEED not currently supported on CH32 + USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_FULL_SPEED; #endif - USBHSD->INT_EN = 0; - USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN | USBHS_ISO_ACT_EN; + USBHSD->INT_EN = 0; + USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN | USBHS_ISO_ACT_EN; - USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; - USBHSD->ENDP_TYPE = 0x00; - USBHSD->BUF_MODE = 0x00; + USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; + USBHSD->ENDP_TYPE = 0x00; + USBHSD->BUF_MODE = 0x00; - for (int ep = 0; ep < EP_MAX; ep++) { - EP_TX_LEN(ep) = 0; - EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; - EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + for (int ep = 0; ep < EP_MAX; ep++) { + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; + EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; - EP_RX_MAX_LEN(ep) = 0; - } + EP_RX_MAX_LEN(ep) = 0; + } - USBHSD->UEP0_DMA = (uint32_t)ep0_data_in_out_buffer; - USBHSD->UEP0_MAX_LEN = CH32_USBHS_EP0_MAX_SIZE; - xfer_status[0][TUSB_DIR_OUT].max_size = CH32_USBHS_EP0_MAX_SIZE; - xfer_status[0][TUSB_DIR_IN].max_size = CH32_USBHS_EP0_MAX_SIZE; + USBHSD->UEP0_DMA = (uint32_t) ep0_buffer; + USBHSD->UEP0_MAX_LEN = CFG_TUD_ENDPOINT0_SIZE; + xfer_status[0][TUSB_DIR_OUT].max_size = CFG_TUD_ENDPOINT0_SIZE; + xfer_status[0][TUSB_DIR_IN].max_size = CFG_TUD_ENDPOINT0_SIZE; - USBHSD->DEV_AD = 0; - USBHSD->CONTROL |= USBHS_DEV_PU_EN; + USBHSD->DEV_AD = 0; + USBHSD->CONTROL |= USBHS_DEV_PU_EN; } void dcd_int_enable(uint8_t rhport) { - (void)rhport; - - NVIC_EnableIRQ(USBHS_IRQn); + (void) rhport; + NVIC_EnableIRQ(USBHS_IRQn); } void dcd_int_disable(uint8_t rhport) { - (void)rhport; - - NVIC_DisableIRQ(USBHS_IRQn); + (void) rhport; + NVIC_DisableIRQ(USBHS_IRQn); } void dcd_edpt_close_all(uint8_t rhport) { - (void)rhport; + (void) rhport; - for (size_t ep = 1; ep < EP_MAX; ep++) { - EP_TX_LEN(ep) = 0; - EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; - EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + for (size_t ep = 1; ep < EP_MAX; ep++) { + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; + EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; - EP_RX_MAX_LEN(ep) = 0; - } + EP_RX_MAX_LEN(ep) = 0; + } - USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; + USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { - (void)dev_addr; + (void) dev_addr; - // Response with zlp status - dcd_edpt_xfer(rhport, 0x80, NULL, 0); + // Response with zlp status + dcd_edpt_xfer(rhport, 0x80, NULL, 0); } void dcd_remote_wakeup(uint8_t rhport) { - (void)rhport; + (void) rhport; } -void dcd_sof_enable(uint8_t rhport, bool en) -{ - (void) rhport; - if (en) { - USBHSD->INT_EN |= USBHS_SOF_ACT_EN; - } else { - USBHSD->INT_EN &= ~(USBHS_SOF_ACT_EN); - } +void dcd_sof_enable(uint8_t rhport, bool en) { + (void) rhport; + if (en) { + USBHSD->INT_EN |= USBHS_SOF_ACT_EN; + } else { + USBHSD->INT_EN &= ~(USBHS_SOF_ACT_EN); + } } -void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { - (void)rhport; +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) { + (void) rhport; - if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && - request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && - request->bRequest == TUSB_REQ_SET_ADDRESS) { - USBHSD->DEV_AD = (uint8_t)request->wValue; - } + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS) { + USBHSD->DEV_AD = (uint8_t) request->wValue; + } - EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; - EP_RX_CTRL(0) = USBHS_EP_R_RES_NAK | USBHS_EP_R_TOG_0; + EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + EP_RX_CTRL(0) = USBHS_EP_R_RES_NAK | USBHS_EP_R_TOG_0; } -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) { - (void)rhport; +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { + (void) rhport; - uint8_t const ep_num = tu_edpt_number(desc_edpt->bEndpointAddress); - tusb_dir_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + uint8_t const ep_num = tu_edpt_number(desc_edpt->bEndpointAddress); + tusb_dir_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); - TU_ASSERT(ep_num < EP_MAX); + TU_ASSERT(ep_num < EP_MAX); - if (ep_num == 0) { - return true; - } + if (ep_num == 0) { + return true; + } - xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, dir); - xfer->max_size = tu_edpt_packet_size(desc_edpt); + xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, dir); + xfer->max_size = tu_edpt_packet_size(desc_edpt); - xfer->is_iso = (desc_edpt->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); - if (dir == TUSB_DIR_OUT) { - USBHSD->ENDP_CONFIG |= (USBHS_EP0_R_EN << ep_num); - EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; - if (xfer->is_iso == true) { - USBHSD->ENDP_TYPE |= (USBHS_EP0_R_TYP << ep_num); - } - EP_RX_MAX_LEN(ep_num) = xfer->max_size; + xfer->is_iso = (desc_edpt->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); + if (dir == TUSB_DIR_OUT) { + USBHSD->ENDP_CONFIG |= (USBHS_EP0_R_EN << ep_num); + EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + if (xfer->is_iso == true) { + USBHSD->ENDP_TYPE |= (USBHS_EP0_R_TYP << ep_num); + } + EP_RX_MAX_LEN(ep_num) = xfer->max_size; + } else { + if (xfer->is_iso == true) { + USBHSD->ENDP_TYPE |= (USBHS_EP0_T_TYP << ep_num); } else { - if (xfer->is_iso == true) { - USBHSD->ENDP_TYPE |= (USBHS_EP0_T_TYP << ep_num); - } else { - /* Enable all types except Isochronous to avoid ISO_ACT interrupt generation */ - USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); - } - EP_TX_LEN(ep_num) = 0; - EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + /* Enable all types except Isochronous to avoid ISO_ACT interrupt generation */ + USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); } + EP_TX_LEN(ep_num) = 0; + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + } - return true; + return true; } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - (void)rhport; - - uint8_t const ep_num = tu_edpt_number(ep_addr); - tusb_dir_t const dir = tu_edpt_dir(ep_addr); - - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; - EP_RX_MAX_LEN(ep_num) = 0; - USBHSD->ENDP_TYPE &= ~(USBHS_EP0_R_TYP << ep_num); - USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_R_EN << ep_num); - } else { // TUSB_DIR_IN - EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; - EP_TX_LEN(ep_num) = 0; - USBHSD->ENDP_TYPE &= ~(USBHS_EP0_T_TYP << ep_num); - USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); - } + (void) rhport; + + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); + + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + EP_RX_MAX_LEN(ep_num) = 0; + USBHSD->ENDP_TYPE &= ~(USBHS_EP0_R_TYP << ep_num); + USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_R_EN << ep_num); + } else { // TUSB_DIR_IN + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + EP_TX_LEN(ep_num) = 0; + USBHSD->ENDP_TYPE &= ~(USBHS_EP0_T_TYP << ep_num); + USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); + } } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { - (void)rhport; + (void) rhport; - uint8_t const ep_num = tu_edpt_number(ep_addr); - tusb_dir_t const dir = tu_edpt_dir(ep_addr); + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(ep_num) = USBHS_EP_R_RES_STALL; - } else { - EP_TX_LEN(0) = 0; - EP_TX_CTRL(ep_num) = USBHS_EP_T_RES_STALL; - } + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep_num) = USBHS_EP_R_RES_STALL; + } else { + EP_TX_LEN(0) = 0; + EP_TX_CTRL(ep_num) = USBHS_EP_T_RES_STALL; + } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { - (void)rhport; + (void) rhport; - uint8_t const ep_num = tu_edpt_number(ep_addr); - tusb_dir_t const dir = tu_edpt_dir(ep_addr); + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; - } else { - EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_R_RES_NAK; - } + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + } else { + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_R_RES_NAK; + } } -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - (void)rhport; - uint8_t const ep_num = tu_edpt_number(ep_addr); - tusb_dir_t const dir = tu_edpt_dir(ep_addr); +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { + (void) rhport; + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); - xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, dir); - xfer->buffer = buffer; - xfer->total_len = total_bytes; - xfer->queued_len = 0; - xfer->is_last_packet = false; + xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, dir); + xfer->buffer = buffer; + xfer->total_len = total_bytes; + xfer->queued_len = 0; + xfer->is_last_packet = false; - xfer_data_packet(ep_addr, xfer); + xfer_data_packet(ep_addr, xfer); - return true; + return true; } void dcd_int_handler(uint8_t rhport) { - (void)rhport; - - uint8_t int_flag = USBHSD->INT_FG; - uint8_t int_status = USBHSD->INT_ST; - - if (int_flag & USBHS_ISO_ACT_FLAG) { - uint8_t ep_num = int_status & MASK_UIS_ENDP; - uint8_t rx_token = int_status & MASK_UIS_TOKEN; - uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; - xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); - - if (rx_token == USBHS_TOKEN_PID_OUT) { - uint16_t rx_len = USBHSD->RX_LEN; - - xfer->queued_len += rx_len; - if (rx_len < xfer->max_size) { - xfer->is_last_packet = true; - } - } else if (rx_token == USBHS_TOKEN_PID_IN) { - if (xfer->is_last_packet == true) { - /* Disable EP to avoid ISO_ACT interrupt generation */ - USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); - } - } + (void) rhport; + + uint8_t int_flag = USBHSD->INT_FG; + uint8_t int_status = USBHSD->INT_ST; + + if (int_flag & USBHS_ISO_ACT_FLAG) { + uint8_t ep_num = int_status & MASK_UIS_ENDP; + uint8_t rx_token = int_status & MASK_UIS_TOKEN; + uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; + xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); + + if (rx_token == USBHS_TOKEN_PID_OUT) { + uint16_t rx_len = USBHSD->RX_LEN; + + xfer->queued_len += rx_len; + if (rx_len < xfer->max_size) { + xfer->is_last_packet = true; + } + } else if (rx_token == USBHS_TOKEN_PID_IN) { + if (xfer->is_last_packet == true) { + /* Disable EP to avoid ISO_ACT interrupt generation */ + USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); + } + } - if (xfer->is_last_packet == true) { - ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); - dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); - } else { - /* prepare next part of packet to xref */ - xfer_data_packet(ep_addr, xfer); + if (xfer->is_last_packet == true) { + ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); + dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } else { + /* prepare next part of packet to xref */ + xfer_data_packet(ep_addr, xfer); + } + + USBHSD->INT_FG = USBHS_ISO_ACT_FLAG; /* Clear flag */ + } else if (int_flag & USBHS_TRANSFER_FLAG) { + + uint8_t ep_num = int_status & MASK_UIS_ENDP; + uint8_t rx_token = int_status & MASK_UIS_TOKEN; + uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; + xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); + + if (xfer->is_iso == false) { + if (rx_token == USBHS_TOKEN_PID_OUT) { + uint16_t rx_len = USBHSD->RX_LEN; + + if (ep_num == 0) { + memcpy(&xfer->buffer[xfer->queued_len], ep0_buffer, rx_len); } - USBHSD->INT_FG = USBHS_ISO_ACT_FLAG; /* Clear flag */ - } else if (int_flag & USBHS_TRANSFER_FLAG) { - - uint8_t ep_num = int_status & MASK_UIS_ENDP; - uint8_t rx_token = int_status & MASK_UIS_TOKEN; - uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; - xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); - - if (xfer->is_iso == false) { - if (rx_token == USBHS_TOKEN_PID_OUT) { - uint16_t rx_len = USBHSD->RX_LEN; - - if (ep_num == 0) { - memcpy(&xfer->buffer[xfer->queued_len], ep0_data_in_out_buffer, rx_len); - } - - xfer->queued_len += rx_len; - if (rx_len < xfer->max_size) { - xfer->is_last_packet = true; - } - - } else if (rx_token == USBHS_TOKEN_PID_IN) { - // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet - // Common processing below - } - - if (xfer->is_last_packet == true) { - ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); - dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); - } else { - /* prepare next part of packet to xref */ - xfer_data_packet(ep_addr, xfer); - } + xfer->queued_len += rx_len; + if (rx_len < xfer->max_size) { + xfer->is_last_packet = true; } - USBHSD->INT_FG = USBHS_TRANSFER_FLAG; /* Clear flag */ - } else if (int_flag & USBHS_SETUP_FLAG) { - ep_set_response_and_toggle(0x80, EP_RESPONSE_NAK); - ep_set_response_and_toggle(0x00, EP_RESPONSE_NAK); - dcd_event_setup_received(0, ep0_data_in_out_buffer, true); + } else if (rx_token == USBHS_TOKEN_PID_IN) { + // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet + // Common processing below + } + + if (xfer->is_last_packet == true) { + ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); + dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } else { + /* prepare next part of packet to xref */ + xfer_data_packet(ep_addr, xfer); + } + } - USBHSD->INT_FG = USBHS_SETUP_FLAG; /* Clear flag */ - } else if (int_flag & USBHS_DETECT_FLAG) { + USBHSD->INT_FG = USBHS_TRANSFER_FLAG; /* Clear flag */ + } else if (int_flag & USBHS_SETUP_FLAG) { + ep_set_response_and_toggle(0x80, EP_RESPONSE_NAK); + ep_set_response_and_toggle(0x00, EP_RESPONSE_NAK); + dcd_event_setup_received(0, ep0_buffer, true); - dcd_event_bus_reset(0, TUSB_SPEED_HIGH, true); + USBHSD->INT_FG = USBHS_SETUP_FLAG; /* Clear flag */ + } else if (int_flag & USBHS_DETECT_FLAG) { - USBHSD->DEV_AD = 0; - EP_RX_CTRL(0) = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; - EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + dcd_event_bus_reset(0, TUSB_SPEED_HIGH, true); - USBHSD->INT_FG = USBHS_DETECT_FLAG; /* Clear flag */ - } else if (int_flag & USBHS_SUSPEND_FLAG) { - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SUSPEND }; - dcd_event_handler(&event, true); + USBHSD->DEV_AD = 0; + EP_RX_CTRL(0) = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; + EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; - USBHSD->INT_FG = USBHS_SUSPEND_FLAG; /* Clear flag */ - } + USBHSD->INT_FG = USBHS_DETECT_FLAG; /* Clear flag */ + } else if (int_flag & USBHS_SUSPEND_FLAG) { + dcd_event_t event = {.rhport = rhport, .event_id = DCD_EVENT_SUSPEND}; + dcd_event_handler(&event, true); + + USBHSD->INT_FG = USBHS_SUSPEND_FLAG; /* Clear flag */ + } } #endif -- cgit v1.3.1 From 953e3bd6344812c910f714952b4dda47ffe53107 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 21 May 2024 16:08:27 +0700 Subject: - minor update to ep_set_response_and_toggle/xfer_data_packet - merge USBHS_ISO_ACT_FLAG, USBHS_TRANSFER_FLAG handler since they are similar - improve uart output - add note for link speed in bus reset --- hw/bsp/ch32v307/debug_uart.c | 2 +- hw/bsp/ch32v307/family.c | 7 +-- src/portable/wch/ch32_usbhs_reg.h | 5 +- src/portable/wch/dcd_ch32_usbhs.c | 104 +++++++++++++++++--------------------- 4 files changed, 54 insertions(+), 64 deletions(-) diff --git a/hw/bsp/ch32v307/debug_uart.c b/hw/bsp/ch32v307/debug_uart.c index db3551ca7..fbabeeadc 100644 --- a/hw/bsp/ch32v307/debug_uart.c +++ b/hw/bsp/ch32v307/debug_uart.c @@ -28,7 +28,7 @@ #include -#define UART_RINGBUFFER_SIZE_TX 64 +#define UART_RINGBUFFER_SIZE_TX 128 #define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1) static char tx_buf[UART_RINGBUFFER_SIZE_TX]; diff --git a/hw/bsp/ch32v307/family.c b/hw/bsp/ch32v307/family.c index fe37ea8e3..94578b416 100644 --- a/hw/bsp/ch32v307/family.c +++ b/hw/bsp/ch32v307/family.c @@ -72,7 +72,7 @@ void board_init(void) { SysTick_Config(SystemCoreClock / 1000); #endif - usart_printf_init(115200); + usart_printf_init(CFG_BOARD_UART_BAUDRATE); #if CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED // Use Highspeed USB @@ -150,10 +150,11 @@ int board_uart_read(uint8_t* buf, int len) { int board_uart_write(void const* buf, int len) { int txsize = len; + const char* bufc = (const char*) buf; while (txsize--) { - uart_write(*(uint8_t const*) buf); - buf++; + uart_write(*bufc++); } + uart_sync(); return len; } diff --git a/src/portable/wch/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h index 7428285a5..1c2ed9893 100644 --- a/src/portable/wch/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -74,7 +74,10 @@ // USB SPEED TYPE #define USBHS_SPEED_TYPE_OFFSET 0x08 -#define USBSPEED_MASK (0x03) +#define USBHS_SPEED_TYPE_MASK 0x03 +#define USBHS_SPEED_TYPE_FULL 0 +#define USBHS_SPEED_TYPE_HIGH 1 +#define USBHS_SPEED_TYPE_LOW 2 // USB_MIS_ST #define USBHS_MIS_ST_OFFSET 0x09 diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index dbcf19a7b..8879db98d 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -64,9 +64,8 @@ static xfer_ctl_t xfer_status[EP_MAX][2]; /* Endpoint Buffer */ TU_ATTR_ALIGNED(4) static uint8_t ep0_buffer[CFG_TUD_ENDPOINT0_SIZE]; -static void ep_set_response_and_toggle(uint8_t ep_addr, ep_response_list_t response_type) { - uint8_t const ep_num = tu_edpt_number(ep_addr); - if (ep_addr & TUSB_DIR_IN_MASK) { +static void ep_set_response_and_toggle(uint8_t ep_num, tusb_dir_t ep_dir, ep_response_list_t response_type) { + if (ep_dir == TUSB_DIR_IN) { uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_T_RES_ACK : USBHS_EP_T_RES_NAK; if (ep_num == 0) { if (response_type == EP_RESPONSE_ACK) { @@ -97,11 +96,8 @@ static void ep_set_response_and_toggle(uint8_t ep_addr, ep_response_list_t respo } } -static void xfer_data_packet(uint8_t ep_addr, xfer_ctl_t* xfer) { - uint8_t const ep_num = tu_edpt_number(ep_addr); - tusb_dir_t const dir = tu_edpt_dir(ep_addr); - - if (dir == TUSB_DIR_IN) { +static void xfer_data_packet(uint8_t ep_num, tusb_dir_t ep_dir, xfer_ctl_t* xfer) { + if (ep_dir == TUSB_DIR_IN) { uint16_t remaining = xfer->total_len - xfer->queued_len; uint16_t next_tx_size = TU_MIN(remaining, xfer->max_size); @@ -133,7 +129,7 @@ static void xfer_data_packet(uint8_t ep_addr, xfer_ctl_t* xfer) { EP_RX_MAX_LEN(ep_num) = max_possible_rx_size; } } - ep_set_response_and_toggle(ep_addr, USBHS_EP_R_RES_ACK); + ep_set_response_and_toggle(ep_num, ep_dir, USBHS_EP_R_RES_ACK); } void dcd_init(uint8_t rhport) { @@ -154,7 +150,7 @@ void dcd_init(uint8_t rhport) { #endif USBHSD->INT_EN = 0; - USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN | USBHS_ISO_ACT_EN; + USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_BUS_RST_EN | USBHS_SUSPEND_EN | USBHS_ISO_ACT_EN; USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; USBHSD->ENDP_TYPE = 0x00; @@ -328,7 +324,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to xfer->queued_len = 0; xfer->is_last_packet = false; - xfer_data_packet(ep_addr, xfer); + xfer_data_packet(ep_num, dir, xfer); return true; } @@ -339,77 +335,67 @@ void dcd_int_handler(uint8_t rhport) { uint8_t int_flag = USBHSD->INT_FG; uint8_t int_status = USBHSD->INT_ST; - if (int_flag & USBHS_ISO_ACT_FLAG) { - uint8_t ep_num = int_status & MASK_UIS_ENDP; - uint8_t rx_token = int_status & MASK_UIS_TOKEN; - uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; - xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); + if (int_flag & (USBHS_ISO_ACT_FLAG | USBHS_TRANSFER_FLAG)) { + uint8_t const rx_token = int_status & MASK_UIS_TOKEN; + uint8_t const ep_num = int_status & MASK_UIS_ENDP; + tusb_dir_t const ep_dir = (rx_token == USBHS_TOKEN_PID_IN) ? TUSB_DIR_IN : TUSB_DIR_OUT; + uint8_t const ep_addr = tu_edpt_addr(ep_num, ep_dir); + xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, ep_dir); if (rx_token == USBHS_TOKEN_PID_OUT) { uint16_t rx_len = USBHSD->RX_LEN; + if (ep_num == 0) { + memcpy(&xfer->buffer[xfer->queued_len], ep0_buffer, rx_len); + } + xfer->queued_len += rx_len; if (rx_len < xfer->max_size) { xfer->is_last_packet = true; } } else if (rx_token == USBHS_TOKEN_PID_IN) { - if (xfer->is_last_packet == true) { + if (xfer->is_iso && xfer->is_last_packet) { /* Disable EP to avoid ISO_ACT interrupt generation */ USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); + }else { + // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet } } if (xfer->is_last_packet == true) { - ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); + ep_set_response_and_toggle(ep_num, ep_dir, EP_RESPONSE_NAK); dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); } else { /* prepare next part of packet to xref */ - xfer_data_packet(ep_addr, xfer); - } - - USBHSD->INT_FG = USBHS_ISO_ACT_FLAG; /* Clear flag */ - } else if (int_flag & USBHS_TRANSFER_FLAG) { - - uint8_t ep_num = int_status & MASK_UIS_ENDP; - uint8_t rx_token = int_status & MASK_UIS_TOKEN; - uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; - xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); - - if (xfer->is_iso == false) { - if (rx_token == USBHS_TOKEN_PID_OUT) { - uint16_t rx_len = USBHSD->RX_LEN; - - if (ep_num == 0) { - memcpy(&xfer->buffer[xfer->queued_len], ep0_buffer, rx_len); - } - - xfer->queued_len += rx_len; - if (rx_len < xfer->max_size) { - xfer->is_last_packet = true; - } - - } else if (rx_token == USBHS_TOKEN_PID_IN) { - // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet - // Common processing below - } - - if (xfer->is_last_packet == true) { - ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); - dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); - } else { - /* prepare next part of packet to xref */ - xfer_data_packet(ep_addr, xfer); - } + xfer_data_packet(ep_num, ep_dir, xfer); } - USBHSD->INT_FG = USBHS_TRANSFER_FLAG; /* Clear flag */ + USBHSD->INT_FG = (int_flag & (USBHS_ISO_ACT_FLAG | USBHS_TRANSFER_FLAG)); /* Clear flag */ } else if (int_flag & USBHS_SETUP_FLAG) { - ep_set_response_and_toggle(0x80, EP_RESPONSE_NAK); - ep_set_response_and_toggle(0x00, EP_RESPONSE_NAK); + ep_set_response_and_toggle(0, TUSB_DIR_IN, EP_RESPONSE_NAK); + ep_set_response_and_toggle(0, TUSB_DIR_OUT, EP_RESPONSE_NAK); dcd_event_setup_received(0, ep0_buffer, true); USBHSD->INT_FG = USBHS_SETUP_FLAG; /* Clear flag */ - } else if (int_flag & USBHS_DETECT_FLAG) { + } else if (int_flag & USBHS_BUS_RST_FLAG) { + // TODO CH32 does not detect actual speed at this time (should be known at end of reset) + // This interrupt probably triggered at start of bus reset +// tusb_speed_t actual_speed; +// switch(USBHSD->SPEED_TYPE & USBHS_SPEED_TYPE_MASK){ +// case USBHS_SPEED_TYPE_HIGH: +// actual_speed = TUSB_SPEED_HIGH; +// break; +// case USBHS_SPEED_TYPE_FULL: +// actual_speed = TUSB_SPEED_FULL; +// break; +// case USBHS_SPEED_TYPE_LOW: +// actual_speed = TUSB_SPEED_LOW; +// break; +// default: +// TU_ASSERT(0,); +// break; +// } +// dcd_event_bus_reset(0, actual_speed, true); dcd_event_bus_reset(0, TUSB_SPEED_HIGH, true); @@ -417,7 +403,7 @@ void dcd_int_handler(uint8_t rhport) { EP_RX_CTRL(0) = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; - USBHSD->INT_FG = USBHS_DETECT_FLAG; /* Clear flag */ + USBHSD->INT_FG = USBHS_BUS_RST_FLAG; /* Clear flag */ } else if (int_flag & USBHS_SUSPEND_FLAG) { dcd_event_t event = {.rhport = rhport, .event_id = DCD_EVENT_SUSPEND}; dcd_event_handler(&event, true); -- cgit v1.3.1 From 4a5b190a2209958b875416641b67a4076f14c9e2 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 21 May 2024 18:34:25 +0700 Subject: re-add sof event --- src/portable/wch/ch32_usbhs_reg.h | 5 ++++ src/portable/wch/dcd_ch32_usbhs.c | 62 +++++++++++++++++++++------------------ 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/portable/wch/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h index 1c2ed9893..130e4f223 100644 --- a/src/portable/wch/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -63,8 +63,13 @@ // USB DEV AD #define USBHS_DEV_AD_OFFSET 0x03 + // USB FRAME_NO #define USBHS_FRAME_NO_OFFSET 0x04 +#define USBHS_FRAME_NO_NUM_MASK (0x7FF) +#define USBHS_FRAME_NO_MICROFRAME_SHIFT (11) +#define USBHS_FRAME_NO_MICROFRAME_MASK (0x7 << USBHS_FRAME_NO_MICROFRAME_SHIFT) + // USB SUSPEND #define USBHS_SUSPEND_OFFSET 0x06 #define USBHS_DEV_REMOTE_WAKEUP (1 << 2) diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 8879db98d..b36c7dd50 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -336,40 +336,46 @@ void dcd_int_handler(uint8_t rhport) { uint8_t int_status = USBHSD->INT_ST; if (int_flag & (USBHS_ISO_ACT_FLAG | USBHS_TRANSFER_FLAG)) { - uint8_t const rx_token = int_status & MASK_UIS_TOKEN; - uint8_t const ep_num = int_status & MASK_UIS_ENDP; - tusb_dir_t const ep_dir = (rx_token == USBHS_TOKEN_PID_IN) ? TUSB_DIR_IN : TUSB_DIR_OUT; - uint8_t const ep_addr = tu_edpt_addr(ep_num, ep_dir); - xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, ep_dir); - - if (rx_token == USBHS_TOKEN_PID_OUT) { - uint16_t rx_len = USBHSD->RX_LEN; + uint8_t const token = int_status & MASK_UIS_TOKEN; + + if (token == USBHS_TOKEN_PID_SOF) { + uint32_t frame_count = USBHSD->FRAME_NO & USBHS_FRAME_NO_NUM_MASK; + dcd_event_sof(rhport, frame_count, true); + }else { + uint8_t const ep_num = int_status & MASK_UIS_ENDP; + tusb_dir_t const ep_dir = (token == USBHS_TOKEN_PID_IN) ? TUSB_DIR_IN : TUSB_DIR_OUT; + uint8_t const ep_addr = tu_edpt_addr(ep_num, ep_dir); + xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, ep_dir); + + if (token == USBHS_TOKEN_PID_OUT) { + uint16_t rx_len = USBHSD->RX_LEN; + + if (ep_num == 0) { + memcpy(&xfer->buffer[xfer->queued_len], ep0_buffer, rx_len); + } - if (ep_num == 0) { - memcpy(&xfer->buffer[xfer->queued_len], ep0_buffer, rx_len); + xfer->queued_len += rx_len; + if (rx_len < xfer->max_size) { + xfer->is_last_packet = true; + } + } else if (token == USBHS_TOKEN_PID_IN) { + if (xfer->is_iso && xfer->is_last_packet) { + /* Disable EP to avoid ISO_ACT interrupt generation */ + USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); + } else { + // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet + } } - xfer->queued_len += rx_len; - if (rx_len < xfer->max_size) { - xfer->is_last_packet = true; - } - } else if (rx_token == USBHS_TOKEN_PID_IN) { - if (xfer->is_iso && xfer->is_last_packet) { - /* Disable EP to avoid ISO_ACT interrupt generation */ - USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); - }else { - // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet + if (xfer->is_last_packet == true) { + ep_set_response_and_toggle(ep_num, ep_dir, EP_RESPONSE_NAK); + dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } else { + /* prepare next part of packet to xref */ + xfer_data_packet(ep_num, ep_dir, xfer); } } - if (xfer->is_last_packet == true) { - ep_set_response_and_toggle(ep_num, ep_dir, EP_RESPONSE_NAK); - dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); - } else { - /* prepare next part of packet to xref */ - xfer_data_packet(ep_num, ep_dir, xfer); - } - USBHSD->INT_FG = (int_flag & (USBHS_ISO_ACT_FLAG | USBHS_TRANSFER_FLAG)); /* Clear flag */ } else if (int_flag & USBHS_SETUP_FLAG) { ep_set_response_and_toggle(0, TUSB_DIR_IN, EP_RESPONSE_NAK); -- cgit v1.3.1 From 927015baae9b2d265d1daaa0fc2ffca1aa4f9e91 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 May 2024 11:38:44 +0700 Subject: wch usbfs/usbhs need to specify which driver to use. for v307 default to highspeed --- hw/bsp/ch32v307/family.c | 13 +++++---- hw/bsp/ch32v307/family.cmake | 15 +++++++--- hw/bsp/ch32v307/family.mk | 4 +-- src/common/tusb_mcu.h | 50 ++++++++++++++++++++++++++-------- src/device/usbd.c | 2 +- src/portable/synopsys/dwc2/dwc2_type.h | 33 ++++++++++++++++------ src/portable/wch/dcd_ch32_usbfs.c | 3 +- src/portable/wch/dcd_ch32_usbhs.c | 3 +- src/tusb_option.h | 47 ++++++++++++++++++-------------- 9 files changed, 114 insertions(+), 56 deletions(-) diff --git a/hw/bsp/ch32v307/family.c b/hw/bsp/ch32v307/family.c index 94578b416..0846b10a9 100644 --- a/hw/bsp/ch32v307/family.c +++ b/hw/bsp/ch32v307/family.c @@ -38,13 +38,13 @@ // TODO maybe having FS as port0, HS as port1 __attribute__((interrupt)) void USBHS_IRQHandler(void) { - #if CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED + #if CFG_TUD_WCH_USBIP_USBHS tud_int_handler(0); #endif } __attribute__((interrupt)) void OTG_FS_IRQHandler(void) { - #if CFG_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED + #if CFG_TUD_WCH_USBIP_USBFS tud_int_handler(0); #endif } @@ -74,15 +74,17 @@ void board_init(void) { usart_printf_init(CFG_BOARD_UART_BAUDRATE); -#if CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED - // Use Highspeed USB +#ifdef CH32V30x_D8C + // v305/v307: Highspeed USB RCC_USBCLK48MConfig(RCC_USBCLK48MCLKSource_USBPHY); RCC_USBHSPLLCLKConfig(RCC_HSBHSPLLCLKSource_HSE); RCC_USBHSConfig(RCC_USBPLL_Div2); RCC_USBHSPLLCKREFCLKConfig(RCC_USBHSPLLCKREFCLK_4M); RCC_USBHSPHYPLLALIVEcmd(ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHS, ENABLE); -#else +#endif + + // Fullspeed USB uint8_t otg_div; switch (SystemCoreClock) { case 48000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div1; break; @@ -92,7 +94,6 @@ void board_init(void) { } RCC_OTGFSCLKConfig(otg_div); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); -#endif GPIO_InitTypeDef GPIO_InitStructure = {0}; diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake index fd475c987..af26bfc31 100644 --- a/hw/bsp/ch32v307/family.cmake +++ b/hw/bsp/ch32v307/family.cmake @@ -14,7 +14,7 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TO set(FAMILY_MCUS CH32V307 CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") -# default to highspeed +# default to highspeed, used to select USBFS / USBHS driver if (NOT DEFINED SPEED) set(SPEED high) endif() @@ -52,9 +52,16 @@ function(add_board_target BOARD_TARGET) ${SDK_SRC_DIR}/Peripheral/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - BOARD_TUD_MAX_SPEED=$,OPT_MODE_HIGH_SPEED,OPT_MODE_FULL_SPEED> - ) + if (SPEED STREQUAL high) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_TUD_WCH_USBIP_USBHS=1 +# BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + ) + else () + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_TUD_WCH_USBIP_USBFS=1 + ) + endif () update_board(${BOARD_TARGET}) diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index 2dbe0c46a..30a070a9b 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -26,11 +26,11 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_CH32V307 \ ifeq ($(SPEED),high) - CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED $(info "Using USBHS driver for HighSpeed mode") + CFLAGS += -DCFG_TUD_WCH_USBIP_USBHS=1 else - CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED $(info "Using USBFS driver for FullSpeed mode") + CFLAGS += -DCFG_TUD_WCH_USBIP_USBFS=1 endif LDFLAGS_GCC += \ diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index abfed2835..af11ecb9b 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -402,28 +402,56 @@ #elif TU_CHECK_MCU(OPT_MCU_F1C100S) #define TUP_DCD_ENDPOINT_MAX 4 -//------------- WCH -------------// -#elif TU_CHECK_MCU(OPT_MCU_CH32V307) - // v307 support both FS and HS +//--------------------------------------------------------------------+ +// WCH +//--------------------------------------------------------------------+ +#elif TU_CHECK_MCU(OPT_MCU_CH32F20X) #define TUP_USBIP_WCH_USBHS #define TUP_USBIP_WCH_USBFS - #define TUP_RHPORT_HIGHSPEED 1 // default to highspeed - #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED ? 16 : 8) + #if !defined(CFG_TUD_WCH_USBIP_USBFS) + #define CFG_TUD_WCH_USBIP_USBFS 0 + #endif -#elif TU_CHECK_MCU(OPT_MCU_CH32F20X) - #define TUP_USBIP_WCH_USBHS - #define TUP_USBIP_WCH_USBFS + #if !defined(CFG_TUD_WCH_USBIP_USBHS) + #define CFG_TUD_WCH_USBIP_USBHS (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) + #endif - #define TUP_RHPORT_HIGHSPEED 1 // default to highspeed - #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED ? 16 : 8) + #define TUP_RHPORT_HIGHSPEED CFG_TUD_WCH_USBIP_USBHS + #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_WCH_USBIP_USBHS ? 16 : 8) #elif TU_CHECK_MCU(OPT_MCU_CH32V20X) + // v20x support both FSDEV (USBD) and USBFS, default to FSDEV #define TUP_USBIP_WCH_USBFS #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_USBIP_FSDEV + #define TUP_USBIP_FSDEV_CH32 -#endif + #if !defined(CFG_TUD_WCH_USBIP_USBFS) + #define CFG_TUD_WCH_USBIP_USBFS 0 + #endif + #if !defined(CFG_TUD_WCH_FSDEV) + #define CFG_TUD_WCH_USBIP_FSDEV (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) + #endif + +#elif TU_CHECK_MCU(OPT_MCU_CH32V307) + // v307 support both FS and HS, default to HS + #define TUP_USBIP_WCH_USBHS + #define TUP_USBIP_WCH_USBFS + + #if !defined(CFG_TUD_WCH_USBIP_USBFS) + #define CFG_TUD_WCH_USBIP_USBFS 0 + #endif + + #if !defined(CFG_TUD_WCH_USBIP_USBHS) + #define CFG_TUD_WCH_USBIP_USBHS (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) + #endif + + #define TUP_RHPORT_HIGHSPEED CFG_TUD_WCH_USBIP_USBHS + #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_WCH_USBIP_USBHS ? 16 : 8) + +#endif //--------------------------------------------------------------------+ // External USB controller diff --git a/src/device/usbd.c b/src/device/usbd.c index 25d890dc7..9a6afd0d1 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -407,7 +407,7 @@ bool tud_init(uint8_t rhport) { // skip if already initialized if (tud_inited()) return true; - TU_LOG_USBD("USBD init on controller %u\r\n", rhport); + TU_LOG_USBD("USBD init on controller %u, Highspeed = %u\r\n", rhport, TUD_OPT_HIGH_SPEED); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(usbd_device_t)); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(dcd_event_t)); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_fifo_t)); diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index c15771237..cb694b326 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -1,17 +1,34 @@ -/** - * @author MCD Application Team - * Ha Thach (tinyusb.org) - * - * @attention - * - *

© Copyright (c) 2019 STMicroelectronics. +/* + * The MIT License (MIT) + * + * Copyright (c) 2024, hathach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +/**

© Copyright (c) 2019 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause - * */ #ifndef _TUSB_DWC2_TYPES_H_ diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index dafe4414e..9ed370b40 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -27,8 +27,7 @@ #include "tusb_option.h" -// Note: CH32 can have both USB FS and HS, only use this driver if CFG_TUD_MAX_SPEED is full speed -#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBFS) && (CFG_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED) +#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBFS) && CFG_TUD_WCH_USBIP_USBFS #include "device/dcd.h" #include "ch32_usbfs_reg.h" diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index b36c7dd50..622f9c508 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -27,8 +27,7 @@ #include "tusb_option.h" -// Note: CH32 can have both USB FS and HS, only use this driver if CFG_TUD_MAX_SPEED is high speed -#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBHS) && (CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED) +#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBHS) && CFG_TUD_WCH_USBIP_USBHS #include "ch32_usbhs_reg.h" #include "device/dcd.h" diff --git a/src/tusb_option.h b/src/tusb_option.h index 318a4c7bd..d74510b60 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -207,19 +207,9 @@ #define OPT_OS_RTTHREAD 6 ///< RT-Thread #define OPT_OS_RTX4 7 ///< Keil RTX 4 -// Allow to use command line to change the config name/location -#ifdef CFG_TUSB_CONFIG_FILE - #include CFG_TUSB_CONFIG_FILE -#else - #include "tusb_config.h" -#endif - -#include "common/tusb_mcu.h" - -//-------------------------------------------------------------------- -// RootHub Mode Configuration -// CFG_TUSB_RHPORTx_MODE contains operation mode and speed for that port -//-------------------------------------------------------------------- +//--------------------------------------------------------------------+ +// Mode and Speed +//--------------------------------------------------------------------+ // Low byte is operational mode #define OPT_MODE_NONE 0x0000 ///< Disabled @@ -233,7 +223,24 @@ #define OPT_MODE_HIGH_SPEED 0x0400 ///< High Speed #define OPT_MODE_SPEED_MASK 0xff00 -//------------- Roothub as Device -------------// +//--------------------------------------------------------------------+ +// Include tusb_config.h and tusb_mcu.h +//--------------------------------------------------------------------+ + +// Allow to use command line to change the config name/location +#ifdef CFG_TUSB_CONFIG_FILE + #include CFG_TUSB_CONFIG_FILE +#else + #include "tusb_config.h" +#endif + +#include "common/tusb_mcu.h" + +//-------------------------------------------------------------------- +// RootHub Mode detection +//-------------------------------------------------------------------- + +//------------- Root hub as Device -------------// #if defined(CFG_TUSB_RHPORT0_MODE) && ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_DEVICE) #define TUD_RHPORT_MODE (CFG_TUSB_RHPORT0_MODE) @@ -261,7 +268,7 @@ // highspeed support indicator #define TUD_OPT_HIGH_SPEED (CFG_TUD_MAX_SPEED ? (CFG_TUD_MAX_SPEED & OPT_MODE_HIGH_SPEED) : TUP_RHPORT_HIGHSPEED) -//------------- Roothub as Host -------------// +//------------- Root hub as Host -------------// #if defined(CFG_TUSB_RHPORT0_MODE) && ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST) #define TUH_RHPORT_MODE (CFG_TUSB_RHPORT0_MODE) @@ -467,26 +474,26 @@ #define CFG_TUH_CDC 0 #endif +// FTDI is not part of CDC class, only to re-use CDC driver API #ifndef CFG_TUH_CDC_FTDI - // FTDI is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_FTDI 0 #endif +// List of product IDs that can use the FTDI CDC driver. 0x0403 is FTDI's VID #ifndef CFG_TUH_CDC_FTDI_VID_PID_LIST - // List of product IDs that can use the FTDI CDC driver. 0x0403 is FTDI's VID #define CFG_TUH_CDC_FTDI_VID_PID_LIST \ {0x0403, 0x6001}, {0x0403, 0x6006}, {0x0403, 0x6010}, {0x0403, 0x6011}, \ {0x0403, 0x6014}, {0x0403, 0x6015}, {0x0403, 0x8372}, {0x0403, 0xFBFA}, \ {0x0403, 0xCD18} #endif +// CP210X is not part of CDC class, only to re-use CDC driver API #ifndef CFG_TUH_CDC_CP210X - // CP210X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CP210X 0 #endif +// List of product IDs that can use the CP210X CDC driver. 0x10C4 is Silicon Labs' VID #ifndef CFG_TUH_CDC_CP210X_VID_PID_LIST - // List of product IDs that can use the CP210X CDC driver. 0x10C4 is Silicon Labs' VID #define CFG_TUH_CDC_CP210X_VID_PID_LIST \ {0x10C4, 0xEA60}, {0x10C4, 0xEA70} #endif @@ -496,8 +503,8 @@ #define CFG_TUH_CDC_CH34X 0 #endif +// List of product IDs that can use the CH34X CDC driver #ifndef CFG_TUH_CDC_CH34X_VID_PID_LIST - // List of product IDs that can use the CH34X CDC driver #define CFG_TUH_CDC_CH34X_VID_PID_LIST \ { 0x1a86, 0x5523 }, /* ch341 chip */ \ { 0x1a86, 0x7522 }, /* ch340k chip */ \ -- cgit v1.3.1 From 4ce439a75a6f7aa995c74e7ac32e70ab8216c771 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 May 2024 13:58:44 +0700 Subject: add ch32 support for fsdev driver. v20x can select fsdev or usbfs with make/cmake PORT=0/1. default to fsdev --- hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h | 1 - hw/bsp/ch32v20x/family.c | 151 +++++-- hw/bsp/ch32v20x/family.cmake | 20 +- hw/bsp/ch32v20x/family.mk | 15 +- hw/bsp/ch32v20x/linker/ch32v20x.ld | 166 +++++++- src/common/tusb_compiler.h | 1 + src/common/tusb_mcu.h | 5 +- src/device/dcd.h | 7 +- src/device/usbd.c | 23 +- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 214 ++-------- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h | 551 ------------------------- src/portable/st/stm32_fsdev/fsdev_ch32.h | 232 +++++++++++ src/portable/st/stm32_fsdev/fsdev_common.h | 391 ++++++++++++++++++ src/portable/st/stm32_fsdev/fsdev_stm32.h | 292 +++++++++++++ src/tusb_option.h | 9 + 15 files changed, 1281 insertions(+), 797 deletions(-) delete mode 100644 src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h create mode 100644 src/portable/st/stm32_fsdev/fsdev_ch32.h create mode 100644 src/portable/st/stm32_fsdev/fsdev_common.h create mode 100644 src/portable/st/stm32_fsdev/fsdev_stm32.h diff --git a/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h b/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h index c8d28d90f..3ed2aef04 100644 --- a/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h +++ b/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h @@ -8,7 +8,6 @@ extern "C" { #define LED_PORT GPIOA #define LED_PIN GPIO_Pin_15 #define LED_STATE_ON 0 -#define LED_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE) #ifdef __cplusplus } diff --git a/hw/bsp/ch32v20x/family.c b/hw/bsp/ch32v20x/family.c index 247dacde6..a0a8c3f50 100644 --- a/hw/bsp/ch32v20x/family.c +++ b/hw/bsp/ch32v20x/family.c @@ -1,82 +1,153 @@ #include #include "ch32v20x.h" + #include "bsp/board_api.h" #include "board.h" -__attribute__((interrupt)) +/* CH32v203 depending on variants can support 2 USB IPs: FSDEV and USBFS. + * By default, we use FSDEV, but you can explicitly select by define: + * - CFG_TUD_WCH_USBIP_FSDEV + * - CFG_TUD_WCH_USBIP_USBFS + */ + +// USBFS +__attribute__((interrupt)) __attribute__((used)) void USBHD_IRQHandler(void) { - tud_int_handler(0); + #if CFG_TUD_WCH_USBIP_USBFS + tud_int_handler(0); + #endif +} + +__attribute__((interrupt)) __attribute__((used)) +void USBHDWakeUp_IRQHandler(void) { + #if CFG_TUD_WCH_USBIP_USBFS + tud_int_handler(0); + #endif +} + +// USBD (fsdev) +__attribute__((interrupt)) __attribute__((used)) +void USB_LP_CAN1_RX0_IRQHandler(void) { + #if CFG_TUD_WCH_USBIP_FSDEV + tud_int_handler(0); + #endif } +__attribute__((interrupt)) __attribute__((used)) +void USB_HP_CAN1_TX_IRQHandler(void) { + #if CFG_TUD_WCH_USBIP_FSDEV + tud_int_handler(0); + #endif + +} + +__attribute__((interrupt)) __attribute__((used)) +void USBWakeUp_IRQHandler(void) { + #if CFG_TUD_WCH_USBIP_FSDEV + tud_int_handler(0); + #endif +} + + #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; __attribute__((interrupt)) void SysTick_Handler(void) { - SysTick->SR = 0; - system_ticks++; + SysTick->SR = 0; + system_ticks++; } uint32_t SysTick_Config(uint32_t ticks) { - NVIC_EnableIRQ(SysTicK_IRQn); - SysTick->CTLR = 0; - SysTick->SR = 0; - SysTick->CNT = 0; - SysTick->CMP = ticks-1; - SysTick->CTLR = 0xF; - return 0; + NVIC_EnableIRQ(SysTicK_IRQn); + SysTick->CTLR = 0; + SysTick->SR = 0; + SysTick->CNT = 0; + SysTick->CMP = ticks - 1; + SysTick->CTLR = 0xF; + return 0; } uint32_t board_millis(void) { - return system_ticks; + return system_ticks; } #endif void board_init(void) { - __disable_irq(); + __disable_irq(); #if CFG_TUSB_OS == OPT_OS_NONE - SysTick_Config(SystemCoreClock / 1000); + SysTick_Config(SystemCoreClock / 1000); #endif - switch (SystemCoreClock) { - case 48000000: RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); break; - case 96000000: RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div2); break; - case 144000000: RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div3); break; - default: TU_ASSERT(0,); break; - } - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); - - LED_CLOCK_EN(); - GPIO_InitTypeDef GPIO_InitStructure = { - .GPIO_Pin = LED_PIN, - .GPIO_Mode = GPIO_Mode_Out_OD, - .GPIO_Speed = GPIO_Speed_50MHz, - }; - GPIO_Init(LED_PORT, &GPIO_InitStructure); - - __enable_irq(); - board_delay(2); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); + + uint8_t usb_div; + switch (SystemCoreClock) { + case 48000000: usb_div = RCC_USBCLKSource_PLLCLK_Div1; break; + case 96000000: usb_div = RCC_USBCLKSource_PLLCLK_Div2; break; + case 144000000: usb_div = RCC_USBCLKSource_PLLCLK_Div3; break; + default: TU_ASSERT(0,); break; + } + RCC_USBCLKConfig(usb_div); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); // FSDEV + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); // USB FS + + GPIO_InitTypeDef GPIO_InitStructure = { + .GPIO_Pin = LED_PIN, + .GPIO_Mode = GPIO_Mode_Out_OD, + .GPIO_Speed = GPIO_Speed_50MHz, + }; + GPIO_Init(LED_PORT, &GPIO_InitStructure); + + // UART TX is PA9 + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); + GPIO_InitTypeDef usart_init = { + .GPIO_Pin = GPIO_Pin_9, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_AF_PP, + }; + GPIO_Init(GPIOA, &usart_init); + + USART_InitTypeDef usart = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_StopBits = USART_StopBits_1, + .USART_Parity = USART_Parity_No, + .USART_Mode = USART_Mode_Tx, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + }; + USART_Init(USART1, &usart); + USART_Cmd(USART1, ENABLE); + + __enable_irq(); + board_delay(2); + + printf("SystemCoreClock = %ld\r\n", SystemCoreClock); } void board_led_write(bool state) { - GPIO_WriteBit(LED_PORT, LED_PIN, state); + GPIO_WriteBit(LED_PORT, LED_PIN, state); } uint32_t board_button_read(void) { - return false; + return false; } int board_uart_read(uint8_t *buf, int len) { - (void) buf; - (void) len; - return 0; + (void) buf; + (void) len; + return 0; } int board_uart_write(void const *buf, int len) { - (void) buf; - (void) len; - return len; + const char *bufc = (const char *) buf; + for (int i = 0; i < len; i++) { + while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); + USART_SendData(USART1, *bufc++); + } + + return len; } diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake index 80b035fc0..3fb1c0e79 100644 --- a/hw/bsp/ch32v20x/family.cmake +++ b/hw/bsp/ch32v20x/family.cmake @@ -14,6 +14,11 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TO set(FAMILY_MCUS CH32V20X CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") +# Port0 use FSDev, Port1 use USBFS +if (NOT DEFINED PORT) + set(PORT 0) +endif() + #------------------------------------ # BOARD_TARGET #------------------------------------ @@ -48,9 +53,20 @@ function(add_board_target BOARD_TARGET) ) target_compile_definitions(${BOARD_TARGET} PUBLIC CH32V20x_${MCU_VARIANT} - BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED ) + if (PORT EQUAL 0) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_TUD_WCH_USBIP_FSDEV=1 + ) + elseif (PORT EQUAL 1) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_TUD_WCH_USBIP_USBFS=1 + ) + else() + message(FATAL_ERROR "Invalid PORT ${PORT}") + endif() + update_board(${BOARD_TARGET}) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") @@ -99,8 +115,10 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_CH32V20X ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC ${TOP}/src/portable/wch/dcd_ch32_usbfs.c + ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ) target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index 5c8b31a1c..49d4d2feb 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -14,13 +14,23 @@ SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 +# Port0 use FSDev, Port1 use USBFS +PORT ?= 0 + CFLAGS += \ -mcmodel=medany \ -ffat-lto-objects \ -flto \ -DCH32V20x_${MCU_VARIANT} \ - -DCFG_TUSB_MCU=OPT_MCU_CH32V20X \ - -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED \ + -DCFG_TUSB_MCU=OPT_MCU_CH32V20X + +ifeq ($(PORT),0) + $(info "Using FSDEV driver") + CFLAGS += -DCFG_TUD_WCH_USBIP_FSDEV=1 +else + $(info "Using USBFS driver") + CFLAGS += -DCFG_TUD_WCH_USBIP_USBFS=1 +endif LDFLAGS_GCC += \ -nostdlib -nostartfiles \ @@ -30,6 +40,7 @@ LD_FILE = $(FAMILY_PATH)/linker/${CH32_FAMILY}.ld SRC_C += \ src/portable/wch/dcd_ch32_usbfs.c \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ $(SDK_SRC_DIR)/Core/core_riscv.c \ $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_gpio.c \ $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_misc.c \ diff --git a/hw/bsp/ch32v20x/linker/ch32v20x.ld b/hw/bsp/ch32v20x/linker/ch32v20x.ld index 6ee2fa1c7..cd5c8dc17 100644 --- a/hw/bsp/ch32v20x/linker/ch32v20x.ld +++ b/hw/bsp/ch32v20x/linker/ch32v20x.ld @@ -1 +1,165 @@ -/* Define default values if not already defined */ __FLASH_SIZE = DEFINED(__flash_size) ? __flash_size : 64K; __RAM_SIZE = DEFINED(__ram_size) ? __ram_size : 20K; MEMORY { FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __FLASH_SIZE RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __RAM_SIZE } ENTRY( _start ) __stack_size = 2048; PROVIDE( _stack_size = __stack_size ); SECTIONS { .init : { _sinit = .; . = ALIGN(4); KEEP(*(SORT_NONE(.init))) . = ALIGN(4); _einit = .; } >FLASH AT>FLASH .vector : { *(.vector); . = ALIGN(64); } >FLASH AT>FLASH .text : { . = ALIGN(4); *(.text) *(.text.*) *(.rodata) *(.rodata*) *(.gnu.linkonce.t.*) . = ALIGN(4); } >FLASH AT>FLASH .fini : { KEEP(*(SORT_NONE(.fini))) . = ALIGN(4); } >FLASH AT>FLASH PROVIDE( _etext = . ); PROVIDE( _eitcm = . ); .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH AT>FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH AT>FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH AT>FLASH .ctors : { /* gcc uses crtbegin.o to find the start of the constructors, so we make sure it is first. Because this is a wildcard, it doesn't matter if the user does not actually link against crtbegin.o; the linker won't look for a file to match a wildcard. The wildcard also means that it doesn't matter which directory crtbegin.o is in. */ KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin?.o(.ctors)) /* We don't want to include the .ctor section from the crtend.o file until after the sorted ctors. The .ctor section from the crtend file contains the end of ctors marker and it must be last */ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) } >FLASH AT>FLASH .dtors : { KEEP (*crtbegin.o(.dtors)) KEEP (*crtbegin?.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) } >FLASH AT>FLASH .dalign : { . = ALIGN(4); PROVIDE(_data_vma = .); } >RAM AT>FLASH .dlalign : { . = ALIGN(4); PROVIDE(_data_lma = .); } >FLASH AT>FLASH .data : { *(.gnu.linkonce.r.*) *(.data .data.*) *(.gnu.linkonce.d.*) . = ALIGN(8); PROVIDE( __global_pointer$ = . + 0x800 ); *(.sdata .sdata.*) *(.sdata2.*) *(.gnu.linkonce.s.*) . = ALIGN(8); *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) . = ALIGN(4); PROVIDE( _edata = .); } >RAM AT>FLASH .bss : { . = ALIGN(4); PROVIDE( _sbss = .); *(.sbss*) *(.gnu.linkonce.sb.*) *(.bss*) *(.gnu.linkonce.b.*) *(COMMON*) . = ALIGN(4); PROVIDE( _ebss = .); } >RAM AT>FLASH PROVIDE( _end = _ebss); PROVIDE( end = . ); .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : { PROVIDE( _heap_end = . ); . = ALIGN(4); PROVIDE(_susrstack = . ); . = . + __stack_size; PROVIDE( _eusrstack = .); } >RAM } +/* Define default values if not already defined */ +__FLASH_SIZE = DEFINED(__flash_size) ? __flash_size : 64K; +__RAM_SIZE = DEFINED(__ram_size) ? __ram_size : 20K; + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __FLASH_SIZE + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __RAM_SIZE +} + +ENTRY( _start ) + +__stack_size = 2048; + +PROVIDE( _stack_size = __stack_size ); + +SECTIONS +{ + .init : + { + _sinit = .; + . = ALIGN(4); + KEEP(*(SORT_NONE(.init))) + . = ALIGN(4); + _einit = .; + } >FLASH AT>FLASH + + .vector : + { + *(.vector); + . = ALIGN(64); + } >FLASH AT>FLASH + + .text : + { + . = ALIGN(4); + *(.text) + *(.text.*) + *(.rodata) + *(.rodata*) + *(.gnu.linkonce.t.*) + . = ALIGN(4); + } >FLASH AT>FLASH + + .fini : + { + KEEP(*(SORT_NONE(.fini))) + . = ALIGN(4); + } >FLASH AT>FLASH + + PROVIDE( _etext = . ); + PROVIDE( _eitcm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH AT>FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH AT>FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH AT>FLASH + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >FLASH AT>FLASH + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >FLASH AT>FLASH + + .dalign : + { + . = ALIGN(4); + PROVIDE(_data_vma = .); + } >RAM AT>FLASH + + .dlalign : + { + . = ALIGN(4); + PROVIDE(_data_lma = .); + } >FLASH AT>FLASH + + .data : + { + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.sdata2.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + . = ALIGN(4); + PROVIDE( _edata = .); + } >RAM AT>FLASH + + .bss : + { + . = ALIGN(4); + PROVIDE( _sbss = .); + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss*) + *(.gnu.linkonce.b.*) + *(COMMON*) + . = ALIGN(4); + PROVIDE( _ebss = .); + } >RAM AT>FLASH + + PROVIDE( _end = _ebss); + PROVIDE( end = . ); + + .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = ALIGN(4); + PROVIDE(_susrstack = . ); + . = . + __stack_size; + PROVIDE( _eusrstack = .); + } >RAM + +} diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 0d5570b1c..ce5566ffe 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -128,6 +128,7 @@ #define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name))) #define TU_ATTR_PACKED __attribute__ ((packed)) #define TU_ATTR_WEAK __attribute__ ((weak)) + // #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f)) #ifndef TU_ATTR_ALWAYS_INLINE // allow to override for debug #define TU_ATTR_ALWAYS_INLINE __attribute__ ((always_inline)) #endif diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index af11ecb9b..c66996c4f 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -423,7 +423,6 @@ #elif TU_CHECK_MCU(OPT_MCU_CH32V20X) // v20x support both FSDEV (USBD) and USBFS, default to FSDEV #define TUP_USBIP_WCH_USBFS - #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_CH32 @@ -431,10 +430,12 @@ #define CFG_TUD_WCH_USBIP_USBFS 0 #endif - #if !defined(CFG_TUD_WCH_FSDEV) + #if !defined(CFG_TUD_WCH_USBIP_FSDEV) #define CFG_TUD_WCH_USBIP_FSDEV (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) #endif + #define TUP_DCD_ENDPOINT_MAX 8 + #elif TU_CHECK_MCU(OPT_MCU_CH32V307) // v307 support both FS and HS, default to HS #define TUP_USBIP_WCH_USBHS diff --git a/src/device/dcd.h b/src/device/dcd.h index 9447d6d9d..2d3dafa4c 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -39,9 +39,6 @@ // Configuration //--------------------------------------------------------------------+ -#ifndef CFG_TUD_ENDPPOINT_MAX - #define CFG_TUD_ENDPPOINT_MAX TUP_DCD_ENDPOINT_MAX -#endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES @@ -149,10 +146,10 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr); void dcd_remote_wakeup(uint8_t rhport); // Connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(uint8_t rhport) TU_ATTR_WEAK; +void dcd_connect(uint8_t rhport); // Disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK; +void dcd_disconnect(uint8_t rhport); // Enable/Disable Start-of-frame interrupt. Default is disabled void dcd_sof_enable(uint8_t rhport, bool en); diff --git a/src/device/usbd.c b/src/device/usbd.c index 9a6afd0d1..88183fad0 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -45,11 +45,6 @@ //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ -TU_ATTR_WEAK bool dcd_deinit(uint8_t rhport) { - (void) rhport; - return false; -} - TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { (void)rhport; (void)eventid; @@ -60,6 +55,19 @@ TU_ATTR_WEAK void tud_sof_cb(uint32_t frame_count) { (void)frame_count; } +TU_ATTR_WEAK bool dcd_deinit(uint8_t rhport) { + (void) rhport; + return false; +} + +TU_ATTR_WEAK void dcd_connect(uint8_t rhport) { + (void) rhport; +} + +TU_ATTR_WEAK void dcd_disconnect(uint8_t rhport) { + (void) rhport; +} + //--------------------------------------------------------------------+ // Device Data //--------------------------------------------------------------------+ @@ -379,19 +387,16 @@ bool tud_remote_wakeup(void) { } bool tud_disconnect(void) { - TU_VERIFY(dcd_disconnect); dcd_disconnect(_usbd_rhport); return true; } bool tud_connect(void) { - TU_VERIFY(dcd_connect); dcd_connect(_usbd_rhport); return true; } -bool tud_sof_cb_enable(bool en) -{ +bool tud_sof_cb_enable(bool en) { usbd_sof_enable(_usbd_rhport, SOF_CONSUMER_USER, en); return true; } diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index a26c66892..9ce37f992 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -102,25 +102,29 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && defined(TUP_USBIP_FSDEV) +#if CFG_TUD_ENABLED && defined(TUP_USBIP_FSDEV) && \ + !(defined(TUP_USBIP_FSDEV_CH32) && CFG_TUD_WCH_USBIP_FSDEV == 0) #include "device/dcd.h" -#ifdef TUP_USBIP_FSDEV_STM32 -// Undefine to reduce the dependence on HAL -#undef USE_HAL_DRIVER -#include "portable/st/stm32_fsdev/dcd_stm32_fsdev.h" +#if defined(TUP_USBIP_FSDEV_STM32) + // Undefine to reduce the dependence on HAL + #undef USE_HAL_DRIVER + #include "fsdev_stm32.h" +#elif defined(TUP_USBIP_FSDEV_CH32) + #include "fsdev_ch32.h" +#else + #error "Unknown USB IP" #endif -/***************************************************** - * Configuration - *****************************************************/ +#include "fsdev_common.h" -// HW supports max of 8 bidirectional endpoints, but this can be reduced to save RAM -// (8u here would mean 8 IN and 8 OUT) -#ifndef MAX_EP_COUNT -#define MAX_EP_COUNT 8U -#endif +//--------------------------------------------------------------------+ +// Configuration +//--------------------------------------------------------------------+ + +// hardware limit endpoint +#define FSDEV_EP_COUNT 8 // If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it // Both of these MUST be a multiple of 2, and are in byte units. @@ -132,11 +136,6 @@ #define DCD_STM32_BTABLE_SIZE (FSDEV_PMA_SIZE - DCD_STM32_BTABLE_BASE) #endif -/*************************************************** - * Checks, structs, defines, function definitions, etc. - */ - -TU_VERIFY_STATIC((MAX_EP_COUNT) <= STFSDEV_EP_COUNT, "Only 8 endpoints supported on the hardware"); TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_SIZE)) <= (FSDEV_PMA_SIZE), "BTABLE does not fit in PMA RAM"); TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligned to 8 bytes"); @@ -162,9 +161,9 @@ typedef struct { bool allocated[2]; } ep_alloc_t; -static xfer_ctl_t xfer_status[MAX_EP_COUNT][2]; +static xfer_ctl_t xfer_status[CFG_TUD_ENDPPOINT_MAX][2]; -static ep_alloc_t ep_alloc_status[STFSDEV_EP_COUNT]; +static ep_alloc_t ep_alloc_status[FSDEV_EP_COUNT]; static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6]; @@ -199,7 +198,7 @@ TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint32_t ep_addr) uint8_t epnum = tu_edpt_number(ep_addr); uint8_t dir = tu_edpt_dir(ep_addr); // Fix -Werror=null-dereference - TU_ASSERT(epnum < MAX_EP_COUNT, &xfer_status[0][0]); + TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX, &xfer_status[0][0]); return &xfer_status[epnum][dir]; } @@ -239,7 +238,7 @@ void dcd_init(uint8_t rhport) USB->ISTR = 0; // Clear pending interrupts // Reset endpoints to disabled - for (uint32_t i = 0; i < STFSDEV_EP_COUNT; i++) { + for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) { // This doesn't clear all bits since some bits are "toggle", but does set the type to DISABLED. pcd_set_endpoint(USB, i, 0u); } @@ -248,43 +247,9 @@ void dcd_init(uint8_t rhport) dcd_handle_bus_reset(); // Enable pull-up if supported - if (dcd_connect) { - dcd_connect(rhport); - } -} - -// Define only on MCU with internal pull-up. BSP can define on MCU without internal PU. -#if defined(USB_BCDR_DPPU) - -// Disable internal D+ PU -void dcd_disconnect(uint8_t rhport) -{ - (void)rhport; - USB->BCDR &= ~(USB_BCDR_DPPU); -} - -// Enable internal D+ PU -void dcd_connect(uint8_t rhport) -{ - (void)rhport; - USB->BCDR |= USB_BCDR_DPPU; -} - -#elif defined(SYSCFG_PMC_USB_PU) // works e.g. on STM32L151 -// Disable internal D+ PU -void dcd_disconnect(uint8_t rhport) -{ - (void)rhport; - SYSCFG->PMC &= ~(SYSCFG_PMC_USB_PU); + dcd_connect(rhport); } -// Enable internal D+ PU -void dcd_connect(uint8_t rhport) -{ - (void)rhport; - SYSCFG->PMC |= SYSCFG_PMC_USB_PU; -} -#endif void dcd_sof_enable(uint8_t rhport, bool en) { @@ -298,126 +263,6 @@ void dcd_sof_enable(uint8_t rhport, bool en) } } -// Enable device interrupt -void dcd_int_enable(uint8_t rhport) -{ - (void)rhport; - // Member here forces write to RAM before allowing ISR to execute - __DSB(); - __ISB(); -#if CFG_TUSB_MCU == OPT_MCU_STM32F0 || CFG_TUSB_MCU == OPT_MCU_STM32L0 || CFG_TUSB_MCU == OPT_MCU_STM32L4 - NVIC_EnableIRQ(USB_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L1 - NVIC_EnableIRQ(USB_LP_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32F3 -// Some STM32F302/F303 devices allow to remap the USB interrupt vectors from -// shared USB/CAN IRQs to separate CAN and USB IRQs. -// This dynamically checks if this remap is active to enable the right IRQs. -#ifdef SYSCFG_CFGR1_USB_IT_RMP - if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) { - NVIC_EnableIRQ(USB_HP_IRQn); - NVIC_EnableIRQ(USB_LP_IRQn); - NVIC_EnableIRQ(USBWakeUp_RMP_IRQn); - } else -#endif - { - NVIC_EnableIRQ(USB_HP_CAN_TX_IRQn); - NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn); - NVIC_EnableIRQ(USBWakeUp_IRQn); - } -#elif CFG_TUSB_MCU == OPT_MCU_STM32F1 - NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn); - NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); - NVIC_EnableIRQ(USBWakeUp_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32G4 - NVIC_EnableIRQ(USB_HP_IRQn); - NVIC_EnableIRQ(USB_LP_IRQn); - NVIC_EnableIRQ(USBWakeUp_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32G0 -#ifdef STM32G0B0xx - NVIC_EnableIRQ(USB_IRQn); -#else - NVIC_EnableIRQ(USB_UCPD1_2_IRQn); -#endif - -#elif CFG_TUSB_MCU == OPT_MCU_STM32H5 - NVIC_EnableIRQ(USB_DRD_FS_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32WB - NVIC_EnableIRQ(USB_HP_IRQn); - NVIC_EnableIRQ(USB_LP_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L5 - NVIC_EnableIRQ(USB_FS_IRQn); - -#else -#error Unknown arch in USB driver -#endif -} - -// Disable device interrupt -void dcd_int_disable(uint8_t rhport) -{ - (void)rhport; - -#if CFG_TUSB_MCU == OPT_MCU_STM32F0 || CFG_TUSB_MCU == OPT_MCU_STM32L0 || CFG_TUSB_MCU == OPT_MCU_STM32L4 - NVIC_DisableIRQ(USB_IRQn); -#elif CFG_TUSB_MCU == OPT_MCU_STM32L1 - NVIC_DisableIRQ(USB_LP_IRQn); -#elif CFG_TUSB_MCU == OPT_MCU_STM32F3 -// Some STM32F302/F303 devices allow to remap the USB interrupt vectors from -// shared USB/CAN IRQs to separate CAN and USB IRQs. -// This dynamically checks if this remap is active to disable the right IRQs. -#ifdef SYSCFG_CFGR1_USB_IT_RMP - if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) { - NVIC_DisableIRQ(USB_HP_IRQn); - NVIC_DisableIRQ(USB_LP_IRQn); - NVIC_DisableIRQ(USBWakeUp_RMP_IRQn); - } else -#endif - { - NVIC_DisableIRQ(USB_HP_CAN_TX_IRQn); - NVIC_DisableIRQ(USB_LP_CAN_RX0_IRQn); - NVIC_DisableIRQ(USBWakeUp_IRQn); - } -#elif CFG_TUSB_MCU == OPT_MCU_STM32F1 - NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn); - NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn); - NVIC_DisableIRQ(USBWakeUp_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32G4 - NVIC_DisableIRQ(USB_HP_IRQn); - NVIC_DisableIRQ(USB_LP_IRQn); - NVIC_DisableIRQ(USBWakeUp_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32G0 -#ifdef STM32G0B0xx - NVIC_DisableIRQ(USB_IRQn); -#else - NVIC_DisableIRQ(USB_UCPD1_2_IRQn); -#endif - -#elif CFG_TUSB_MCU == OPT_MCU_STM32H5 - NVIC_DisableIRQ(USB_DRD_FS_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32WB - NVIC_DisableIRQ(USB_HP_IRQn); - NVIC_DisableIRQ(USB_LP_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L5 - NVIC_DisableIRQ(USB_FS_IRQn); - -#else -#error Unknown arch in USB driver -#endif - - // CMSIS has a membar after disabling interrupts -} - // Receive Set Address request, mcu port must also include status IN response void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { @@ -461,7 +306,7 @@ static void dcd_handle_bus_reset(void) { USB->DADDR = 0u; // disable USB peripheral by clearing the EF flag - for (uint32_t i = 0; i < STFSDEV_EP_COUNT; i++) { + for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) { // Clear EP allocation status ep_alloc_status[i].ep_num = 0xFF; ep_alloc_status[i].ep_type = 0xFF; @@ -470,7 +315,7 @@ static void dcd_handle_bus_reset(void) } // Reset PMA allocation - ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * MAX_EP_COUNT; + ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX; dcd_edpt_open(0, &ep0OUT_desc); dcd_edpt_open(0, &ep0IN_desc); @@ -653,7 +498,6 @@ static void dcd_ep_ctr_handler(void) void dcd_int_handler(uint8_t rhport) { - (void)rhport; uint32_t int_status = USB->ISTR; @@ -774,7 +618,7 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - for (uint8_t i = 0; i < STFSDEV_EP_COUNT; i++) { + for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) { // Check if already allocated if (ep_alloc_status[i].allocated[dir] && ep_alloc_status[i].ep_type == ep_type && @@ -818,7 +662,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) uint16_t pma_addr; uint32_t wType; - TU_ASSERT(ep_idx < STFSDEV_EP_COUNT); + TU_ASSERT(ep_idx < FSDEV_EP_COUNT); TU_ASSERT(buffer_size <= 64); // Set type @@ -865,7 +709,7 @@ void dcd_edpt_close_all(uint8_t rhport) { (void)rhport; - for (uint32_t i = 1; i < STFSDEV_EP_COUNT; i++) { + for (uint32_t i = 1; i < FSDEV_EP_COUNT; i++) { // Reset endpoint pcd_set_endpoint(USB, i, 0); // Clear EP allocation status @@ -876,7 +720,7 @@ void dcd_edpt_close_all(uint8_t rhport) } // Reset PMA allocation - ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * MAX_EP_COUNT + 2 * CFG_TUD_ENDPOINT0_SIZE; + ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE; } /** @@ -1155,7 +999,7 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui } if (wNBytes) { - temp1 = *srcVal; + temp1 = (uint16_t) *srcVal; *pdwVal = temp1; } diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h deleted file mode 100644 index 7992f34a1..000000000 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h +++ /dev/null @@ -1,551 +0,0 @@ -/* - * Copyright(c) 2016 STMicroelectronics - * Copyright(c) N Conrad - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the TinyUSB stack. - */ - -// This file contains source copied from ST's HAL, and thus should have their copyright statement. - -// FSDEV_PMA_SIZE is PMA buffer size in bytes. -// On 512-byte devices, access with a stride of two words (use every other 16-bit address) -// On 1024-byte devices, access with a stride of one word (use every 16-bit address) - -#ifndef PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ -#define PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ - -#if CFG_TUSB_MCU == OPT_MCU_STM32F0 - #include "stm32f0xx.h" - #define FSDEV_PMA_SIZE (1024u) - // F0x2 models are crystal-less - // All have internal D+ pull-up - // 070RB: 2 x 16 bits/word memory LPM Support, BCD Support - // PMA dedicated to USB (no sharing with CAN) - -#elif CFG_TUSB_MCU == OPT_MCU_STM32F1 - #include "stm32f1xx.h" - #define FSDEV_PMA_SIZE (512u) - // NO internal Pull-ups - // *B, and *C: 2 x 16 bits/word - - // F1 names this differently from the rest - #define USB_CNTR_LPMODE USB_CNTR_LP_MODE - -#elif defined(STM32F302xB) || defined(STM32F302xC) || \ - defined(STM32F303xB) || defined(STM32F303xC) || \ - defined(STM32F373xC) - #include "stm32f3xx.h" - #define FSDEV_PMA_SIZE (512u) - // NO internal Pull-ups - // *B, and *C: 1 x 16 bits/word - // PMA dedicated to USB (no sharing with CAN) - -#elif defined(STM32F302x6) || defined(STM32F302x8) || \ - defined(STM32F302xD) || defined(STM32F302xE) || \ - defined(STM32F303xD) || defined(STM32F303xE) - #include "stm32f3xx.h" - #define FSDEV_PMA_SIZE (1024u) - // NO internal Pull-ups - // *6, *8, *D, and *E: 2 x 16 bits/word LPM Support - // When CAN clock is enabled, USB can use first 768 bytes ONLY. - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L0 - #include "stm32l0xx.h" - #define FSDEV_PMA_SIZE (1024u) - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L1 - #include "stm32l1xx.h" - #define FSDEV_PMA_SIZE (512u) - -#elif CFG_TUSB_MCU == OPT_MCU_STM32G4 - #include "stm32g4xx.h" - #define FSDEV_PMA_SIZE (1024u) - -#elif CFG_TUSB_MCU == OPT_MCU_STM32G0 - #include "stm32g0xx.h" - #define FSDEV_BUS_32BIT - #define FSDEV_PMA_SIZE (2048u) - #undef USB_PMAADDR - #define USB_PMAADDR USB_DRD_PMAADDR - #define USB_TypeDef USB_DRD_TypeDef - #define EP0R CHEP0R - #define USB_EP_CTR_RX USB_EP_VTRX - #define USB_EP_CTR_TX USB_EP_VTTX - #define USB_EP_T_FIELD USB_CHEP_UTYPE - #define USB_EPREG_MASK USB_CHEP_REG_MASK - #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK - #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK - #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 - #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 - #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 - #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 - #define USB_EPRX_STAT USB_CH_RX_VALID - #define USB_EPKIND_MASK USB_EP_KIND_MASK - #define USB USB_DRD_FS - #define USB_CNTR_FRES USB_CNTR_USBRST - #define USB_CNTR_RESUME USB_CNTR_L2RES - #define USB_ISTR_EP_ID USB_ISTR_IDN - #define USB_EPADDR_FIELD USB_CHEP_ADDR - #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY - #define USB_CNTR_FSUSP USB_CNTR_SUSPEN - -#elif CFG_TUSB_MCU == OPT_MCU_STM32H5 - #include "stm32h5xx.h" - #define FSDEV_BUS_32BIT - - #if !defined(USB_DRD_BASE) && defined(USB_DRD_FS_BASE) - #define USB_DRD_BASE USB_DRD_FS_BASE - #endif - - #define FSDEV_PMA_SIZE (2048u) - #undef USB_PMAADDR - #define USB_PMAADDR USB_DRD_PMAADDR - #define USB_TypeDef USB_DRD_TypeDef - #define EP0R CHEP0R - #define USB_EP_CTR_RX USB_EP_VTRX - #define USB_EP_CTR_TX USB_EP_VTTX - #define USB_EP_T_FIELD USB_CHEP_UTYPE - #define USB_EPREG_MASK USB_CHEP_REG_MASK - #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK - #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK - #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 - #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 - #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 - #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 - #define USB_EPRX_STAT USB_CH_RX_VALID - #define USB_EPKIND_MASK USB_EP_KIND_MASK - #define USB USB_DRD_FS - #define USB_CNTR_FRES USB_CNTR_USBRST - #define USB_CNTR_RESUME USB_CNTR_L2RES - #define USB_ISTR_EP_ID USB_ISTR_IDN - #define USB_EPADDR_FIELD USB_CHEP_ADDR - #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY - #define USB_CNTR_FSUSP USB_CNTR_SUSPEN - -#elif CFG_TUSB_MCU == OPT_MCU_STM32WB - #include "stm32wbxx.h" - #define FSDEV_PMA_SIZE (1024u) - /* ST provided header has incorrect value */ - #undef USB_PMAADDR - #define USB_PMAADDR USB1_PMAADDR - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L4 - #include "stm32l4xx.h" - #define FSDEV_PMA_SIZE (1024u) - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L5 - #include "stm32l5xx.h" - #define FSDEV_PMA_SIZE (1024u) - - #ifndef USB_PMAADDR - #define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS)) - #endif - -#else - #error You are using an untested or unimplemented STM32 variant. Please update the driver. - // This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4 -#endif - -// For purposes of accessing the packet -#if ((FSDEV_PMA_SIZE) == 512u) - #define FSDEV_PMA_STRIDE (2u) -#elif ((FSDEV_PMA_SIZE) == 1024u) - #define FSDEV_PMA_STRIDE (1u) -#endif - -// The fsdev_bus_t type can be used for both register and PMA access necessities -// For type-safety create a new macro for the volatile address of PMAADDR -// The compiler should warn us if we cast it to a non-volatile type? -#ifdef FSDEV_BUS_32BIT -typedef uint32_t fsdev_bus_t; -static __IO uint32_t * const pma32 = (__IO uint32_t*)USB_PMAADDR; - -#else -typedef uint16_t fsdev_bus_t; -// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) -static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; - -TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) { - size_t total_word_offset = (((USBx)->BTABLE)>>1) + x; - total_word_offset *= FSDEV_PMA_STRIDE; - return &(pma[total_word_offset]); -} - -TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) { - return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 1u); -} - -TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) { - return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 3u); -} -#endif - -/* Aligned buffer size according to hardware */ -TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t size) { - /* The STM32 full speed USB peripheral supports only a limited set of - * buffer sizes given by the RX buffer entry format in the USB_BTABLE. */ - uint16_t blocksize = (size > 62) ? 32 : 2; - - // Round up while dividing requested size by blocksize - uint16_t numblocks = (size + blocksize - 1) / blocksize ; - - return numblocks * blocksize; -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - __O uint32_t *reg = (__O uint32_t *)(USB_DRD_BASE + bEpIdx*4); - *reg = wRegValue; -#else - __O uint16_t *reg = (__O uint16_t *)((&USBx->EP0R) + bEpIdx*2u); - *reg = (uint16_t)wRegValue; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - __I uint32_t *reg = (__I uint32_t *)(USB_DRD_BASE + bEpIdx*4); -#else - __I uint16_t *reg = (__I uint16_t *)((&USBx->EP0R) + bEpIdx*2u); -#endif - return *reg; -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= (uint32_t)USB_EP_T_MASK; - regVal |= wType; - regVal |= USB_EP_CTR_RX | USB_EP_CTR_TX; // These clear on write0, so must set high - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_eptype(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EP_T_FIELD; - return regVal; -} - -/** - * @brief Clears bit CTR_RX / CTR_TX in the endpoint register. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal &= ~USB_EP_CTR_RX; - regVal |= USB_EP_CTR_TX; // preserve CTR_TX (clears on writing 0) - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal &= ~USB_EP_CTR_TX; - regVal |= USB_EP_CTR_RX; // preserve CTR_RX (clears on writing 0) - pcd_set_endpoint(USBx, bEpIdx,regVal); -} - -/** - * @brief gets counter of the tx buffer. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @retval Counter value - */ -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - return (pma32[2*bEpIdx] & 0x03FF0000) >> 16; -#else - __I uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpIdx); - return *regPtr & 0x3ffU; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - return (pma32[2*bEpIdx + 1] & 0x03FF0000) >> 16; -#else - __I uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpIdx); - return *regPtr & 0x3ffU; -#endif -} - -#define pcd_get_ep_dbuf0_cnt pcd_get_ep_tx_cnt -#define pcd_get_ep_dbuf1_cnt pcd_get_ep_rx_cnt - -/** - * @brief Sets address in an endpoint register. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @param bAddr Address. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal |= bAddr; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx,regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - return pma32[2*bEpIdx] & 0x0000FFFFu ; -#else - return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u); -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - return pma32[2*bEpIdx + 1] & 0x0000FFFFu; -#else - return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u); -#endif -} - -#define pcd_get_ep_dbuf0_address pcd_get_ep_tx_address -#define pcd_get_ep_dbuf1_address pcd_get_ep_rx_address - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - pma32[2*bEpIdx] = (pma32[2*bEpIdx] & 0xFFFF0000u) | (addr & 0x0000FFFCu); -#else - *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u) = addr; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & 0xFFFF0000u) | (addr & 0x0000FFFCu); -#else - *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u) = addr; -#endif -} - -#define pcd_set_ep_dbuf0_address pcd_set_ep_tx_address -#define pcd_set_ep_dbuf1_address pcd_set_ep_rx_address - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - pma32[2*bEpIdx] = (pma32[2*bEpIdx] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); -#else - __IO uint16_t * reg = pcd_ep_tx_cnt_ptr(USBx, bEpIdx); - *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); -#endif -} - -#define pcd_set_ep_tx_dbuf0_cnt pcd_set_ep_tx_cnt - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_dbuf1_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); -#else - __IO uint16_t * reg = pcd_ep_rx_cnt_ptr(USBx, bEpIdx); - *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDef * USBx, uint32_t rxtx_idx, - uint32_t blocksize, uint32_t numblocks) { - /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ -#ifdef FSDEV_BUS_32BIT - (void) USBx; - pma32[rxtx_idx] = (pma32[rxtx_idx] & 0x0000FFFFu) | (blocksize << 31) | ((numblocks - blocksize) << 26); -#else - __IO uint16_t *pdwReg = pcd_btable_word_ptr(USBx, rxtx_idx*2u + 1u); - *pdwReg = (blocksize << 15) | ((numblocks - blocksize) << 10); -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx, uint32_t rxtx_idx, uint32_t wCount) { - wCount = pcd_aligned_buffer_size(wCount); - - /* We assume that the buffer size is already aligned to hardware requirements. */ - uint16_t blocksize = (wCount > 62) ? 1 : 0; - uint16_t numblocks = wCount / (blocksize ? 32 : 2); - - /* There should be no remainder in the above calculation */ - TU_ASSERT((wCount - (numblocks * (blocksize ? 32 : 2))) == 0, /**/); - - /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ - pcd_set_ep_blsize_num_blocks(USBx, rxtx_idx, blocksize, numblocks); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_dbuf0_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { - pcd_set_ep_bufsize(USBx, 2*bEpIdx, wCount); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { - pcd_set_ep_bufsize(USBx, 2*bEpIdx + 1, wCount); -} - -#define pcd_set_ep_rx_dbuf1_cnt pcd_set_ep_rx_cnt - -/** - * @brief sets the status for tx transfer (bits STAT_TX[1:0]). - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @param wState new state - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPTX_DTOGMASK; - - /* toggle first bit ? */ - if((USB_EPTX_DTOG1 & (wState))!= 0U) - { - regVal ^= USB_EPTX_DTOG1; - } - /* toggle second bit ? */ - if((USB_EPTX_DTOG2 & ((uint32_t)(wState)))!= 0U) - { - regVal ^= USB_EPTX_DTOG2; - } - - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -/** - * @brief sets the status for rx transfer (bits STAT_TX[1:0]) - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @param wState new state - * @retval None - */ - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPRX_DTOGMASK; - - /* toggle first bit ? */ - if((USB_EPRX_DTOG1 & wState)!= 0U) { - regVal ^= USB_EPRX_DTOG1; - } - /* toggle second bit ? */ - if((USB_EPRX_DTOG2 & wState)!= 0U) { - regVal ^= USB_EPRX_DTOG2; - } - - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - return (regVal & USB_EPRX_STAT) >> (12u); -} - - -/** - * @brief Toggles DTOG_RX / DTOG_TX bit in the endpoint register. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -/** - * @brief Clears DTOG_RX / DTOG_TX bit in the endpoint register. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - if((regVal & USB_EP_DTOG_RX) != 0) { - pcd_rx_dtog(USBx,bEpIdx); - } -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - if((regVal & USB_EP_DTOG_TX) != 0) { - pcd_tx_dtog(USBx,bEpIdx); - } -} - -/** - * @brief set & clear EP_KIND bit. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal |= USB_EP_KIND; - regVal &= USB_EPREG_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPKIND_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -// This checks if the device has "LPM" -#if defined(USB_ISTR_L1REQ) -#define USB_ISTR_L1REQ_FORCED (USB_ISTR_L1REQ) -#else -#define USB_ISTR_L1REQ_FORCED ((uint16_t)0x0000U) -#endif - -#define USB_ISTR_ALL_EVENTS (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_WKUP | USB_ISTR_SUSP | \ - USB_ISTR_RESET | USB_ISTR_SOF | USB_ISTR_ESOF | USB_ISTR_L1REQ_FORCED ) - -// Number of endpoints in hardware -// TODO should use TUP_DCD_ENDPOINT_MAX -#define STFSDEV_EP_COUNT (8u) - -#endif /* PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ */ diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h new file mode 100644 index 000000000..85fe3266c --- /dev/null +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -0,0 +1,232 @@ +/* +* The MIT License (MIT) + * + * Copyright (c) 2024, hathach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +/**

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + */ + +#ifndef TUSB_FSDEV_CH32_H +#define TUSB_FSDEV_CH32_H + +#include "common/tusb_compiler.h" + +#if CFG_TUSB_MCU == OPT_MCU_CH32V20X + #include + +#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X + #include +#endif + +#define FSDEV_PMA_SIZE (512u) + +// volatile 32-bit aligned +#define _va32 volatile TU_ATTR_ALIGNED(4) + +typedef struct { + _va32 uint16_t EP0R; // 00: USB Endpoint 0 register + _va32 uint16_t EP1R; // 04: USB Endpoint 1 register + _va32 uint16_t EP2R; // 08: USB Endpoint 2 register + _va32 uint16_t EP3R; // 0C: USB Endpoint 3 register + _va32 uint16_t EP4R; // 10: USB Endpoint 4 register + _va32 uint16_t EP5R; // 14: USB Endpoint 5 register + _va32 uint16_t EP6R; // 18: USB Endpoint 6 register + _va32 uint16_t EP7R; // 1C: USB Endpoint 7 register + _va32 uint16_t RESERVED7[16]; // Reserved + _va32 uint16_t CNTR; // 40: Control register + _va32 uint16_t ISTR; // 44: Interrupt status register + _va32 uint16_t FNR; // 48: Frame number register + _va32 uint16_t DADDR; // 4C: Device address register + _va32 uint16_t BTABLE; // 50: Buffer Table address register +} USB_TypeDef; + +TU_VERIFY_STATIC(sizeof(USB_TypeDef) == 0x54, "Size is not correct"); +TU_VERIFY_STATIC(offsetof(USB_TypeDef, CNTR) == 0x40, "Wrong offset"); + +#define USB_BASE (APB1PERIPH_BASE + 0x00005C00UL) /*!< USB_IP Peripheral Registers base address */ +#define USB_PMAADDR (APB1PERIPH_BASE + 0x00006000UL) /*!< USB_IP Packet Memory Area base address */ +#define USB ((USB_TypeDef *)USB_BASE) + +/******************************************************************************/ +/* */ +/* USB Device General registers */ +/* */ +/******************************************************************************/ +#define USB_CNTR (USB_BASE + 0x40U) /*!< Control register */ +#define USB_ISTR (USB_BASE + 0x44U) /*!< Interrupt status register */ +#define USB_FNR (USB_BASE + 0x48U) /*!< Frame number register */ +#define USB_DADDR (USB_BASE + 0x4CU) /*!< Device address register */ +#define USB_BTABLE (USB_BASE + 0x50U) /*!< Buffer Table address register */ + +/**************************** ISTR interrupt events *************************/ +#define USB_ISTR_CTR ((uint16_t)0x8000U) /*!< Correct TRansfer (clear-only bit) */ +#define USB_ISTR_PMAOVR ((uint16_t)0x4000U) /*!< DMA OVeR/underrun (clear-only bit) */ +#define USB_ISTR_ERR ((uint16_t)0x2000U) /*!< ERRor (clear-only bit) */ +#define USB_ISTR_WKUP ((uint16_t)0x1000U) /*!< WaKe UP (clear-only bit) */ +#define USB_ISTR_SUSP ((uint16_t)0x0800U) /*!< SUSPend (clear-only bit) */ +#define USB_ISTR_RESET ((uint16_t)0x0400U) /*!< RESET (clear-only bit) */ +#define USB_ISTR_SOF ((uint16_t)0x0200U) /*!< Start Of Frame (clear-only bit) */ +#define USB_ISTR_ESOF ((uint16_t)0x0100U) /*!< Expected Start Of Frame (clear-only bit) */ +#define USB_ISTR_DIR ((uint16_t)0x0010U) /*!< DIRection of transaction (read-only bit) */ +#define USB_ISTR_EP_ID ((uint16_t)0x000FU) /*!< EndPoint IDentifier (read-only bit) */ + +/* Legacy defines */ +#define USB_ISTR_PMAOVRM USB_ISTR_PMAOVR + +#define USB_CLR_CTR (~USB_ISTR_CTR) /*!< clear Correct TRansfer bit */ +#define USB_CLR_PMAOVR (~USB_ISTR_PMAOVR) /*!< clear DMA OVeR/underrun bit*/ +#define USB_CLR_ERR (~USB_ISTR_ERR) /*!< clear ERRor bit */ +#define USB_CLR_WKUP (~USB_ISTR_WKUP) /*!< clear WaKe UP bit */ +#define USB_CLR_SUSP (~USB_ISTR_SUSP) /*!< clear SUSPend bit */ +#define USB_CLR_RESET (~USB_ISTR_RESET) /*!< clear RESET bit */ +#define USB_CLR_SOF (~USB_ISTR_SOF) /*!< clear Start Of Frame bit */ +#define USB_CLR_ESOF (~USB_ISTR_ESOF) /*!< clear Expected Start Of Frame bit */ + +/* Legacy defines */ +#define USB_CLR_PMAOVRM USB_CLR_PMAOVR + +/************************* CNTR control register bits definitions ***********/ +#define USB_CNTR_CTRM ((uint16_t)0x8000U) /*!< Correct TRansfer Mask */ +#define USB_CNTR_PMAOVR ((uint16_t)0x4000U) /*!< DMA OVeR/underrun Mask */ +#define USB_CNTR_ERRM ((uint16_t)0x2000U) /*!< ERRor Mask */ +#define USB_CNTR_WKUPM ((uint16_t)0x1000U) /*!< WaKe UP Mask */ +#define USB_CNTR_SUSPM ((uint16_t)0x0800U) /*!< SUSPend Mask */ +#define USB_CNTR_RESETM ((uint16_t)0x0400U) /*!< RESET Mask */ +#define USB_CNTR_SOFM ((uint16_t)0x0200U) /*!< Start Of Frame Mask */ +#define USB_CNTR_ESOFM ((uint16_t)0x0100U) /*!< Expected Start Of Frame Mask */ +#define USB_CNTR_RESUME ((uint16_t)0x0010U) /*!< RESUME request */ +#define USB_CNTR_FSUSP ((uint16_t)0x0008U) /*!< Force SUSPend */ +#define USB_CNTR_LPMODE ((uint16_t)0x0004U) /*!< Low-power MODE */ +#define USB_CNTR_PDWN ((uint16_t)0x0002U) /*!< Power DoWN */ +#define USB_CNTR_FRES ((uint16_t)0x0001U) /*!< Force USB RESet */ + +/* Legacy defines */ +#define USB_CNTR_PMAOVRM USB_CNTR_PMAOVR +#define USB_CNTR_LP_MODE USB_CNTR_LPMODE + +/******************** FNR Frame Number Register bit definitions ************/ +#define USB_FNR_RXDP ((uint16_t)0x8000U) /*!< status of D+ data line */ +#define USB_FNR_RXDM ((uint16_t)0x4000U) /*!< status of D- data line */ +#define USB_FNR_LCK ((uint16_t)0x2000U) /*!< LoCKed */ +#define USB_FNR_LSOF ((uint16_t)0x1800U) /*!< Lost SOF */ +#define USB_FNR_FN ((uint16_t)0x07FFU) /*!< Frame Number */ + +/******************** DADDR Device ADDRess bit definitions ****************/ +#define USB_DADDR_EF ((uint8_t)0x80U) /*!< USB device address Enable Function */ +#define USB_DADDR_ADD ((uint8_t)0x7FU) /*!< USB device address */ + +/****************************** Endpoint register *************************/ +#define USB_EP0R USB_BASE /*!< endpoint 0 register address */ +#define USB_EP1R (USB_BASE + 0x04U) /*!< endpoint 1 register address */ +#define USB_EP2R (USB_BASE + 0x08U) /*!< endpoint 2 register address */ +#define USB_EP3R (USB_BASE + 0x0CU) /*!< endpoint 3 register address */ +#define USB_EP4R (USB_BASE + 0x10U) /*!< endpoint 4 register address */ +#define USB_EP5R (USB_BASE + 0x14U) /*!< endpoint 5 register address */ +#define USB_EP6R (USB_BASE + 0x18U) /*!< endpoint 6 register address */ +#define USB_EP7R (USB_BASE + 0x1CU) /*!< endpoint 7 register address */ +/* bit positions */ +#define USB_EP_CTR_RX ((uint16_t)0x8000U) /*!< EndPoint Correct TRansfer RX */ +#define USB_EP_DTOG_RX ((uint16_t)0x4000U) /*!< EndPoint Data TOGGLE RX */ +#define USB_EPRX_STAT ((uint16_t)0x3000U) /*!< EndPoint RX STATus bit field */ +#define USB_EP_SETUP ((uint16_t)0x0800U) /*!< EndPoint SETUP */ +#define USB_EP_T_FIELD ((uint16_t)0x0600U) /*!< EndPoint TYPE */ +#define USB_EP_KIND ((uint16_t)0x0100U) /*!< EndPoint KIND */ +#define USB_EP_CTR_TX ((uint16_t)0x0080U) /*!< EndPoint Correct TRansfer TX */ +#define USB_EP_DTOG_TX ((uint16_t)0x0040U) /*!< EndPoint Data TOGGLE TX */ +#define USB_EPTX_STAT ((uint16_t)0x0030U) /*!< EndPoint TX STATus bit field */ +#define USB_EPADDR_FIELD ((uint16_t)0x000FU) /*!< EndPoint ADDRess FIELD */ + +/* EndPoint REGister MASK (no toggle fields) */ +#define USB_EPREG_MASK (USB_EP_CTR_RX|USB_EP_SETUP|USB_EP_T_FIELD|USB_EP_KIND|USB_EP_CTR_TX|USB_EPADDR_FIELD) + /*!< EP_TYPE[1:0] EndPoint TYPE */ +#define USB_EP_TYPE_MASK ((uint16_t)0x0600U) /*!< EndPoint TYPE Mask */ +#define USB_EP_BULK ((uint16_t)0x0000U) /*!< EndPoint BULK */ +#define USB_EP_CONTROL ((uint16_t)0x0200U) /*!< EndPoint CONTROL */ +#define USB_EP_ISOCHRONOUS ((uint16_t)0x0400U) /*!< EndPoint ISOCHRONOUS */ +#define USB_EP_INTERRUPT ((uint16_t)0x0600U) /*!< EndPoint INTERRUPT */ +#define USB_EP_T_MASK ((uint16_t) ~USB_EP_T_FIELD & USB_EPREG_MASK) + +#define USB_EPKIND_MASK ((uint16_t) ~USB_EP_KIND & USB_EPREG_MASK) /*!< EP_KIND EndPoint KIND */ + /*!< STAT_TX[1:0] STATus for TX transfer */ +#define USB_EP_TX_DIS ((uint16_t)0x0000U) /*!< EndPoint TX DISabled */ +#define USB_EP_TX_STALL ((uint16_t)0x0010U) /*!< EndPoint TX STALLed */ +#define USB_EP_TX_NAK ((uint16_t)0x0020U) /*!< EndPoint TX NAKed */ +#define USB_EP_TX_VALID ((uint16_t)0x0030U) /*!< EndPoint TX VALID */ +#define USB_EPTX_DTOG1 ((uint16_t)0x0010U) /*!< EndPoint TX Data TOGgle bit1 */ +#define USB_EPTX_DTOG2 ((uint16_t)0x0020U) /*!< EndPoint TX Data TOGgle bit2 */ +#define USB_EPTX_DTOGMASK (USB_EPTX_STAT|USB_EPREG_MASK) + /*!< STAT_RX[1:0] STATus for RX transfer */ +#define USB_EP_RX_DIS ((uint16_t)0x0000U) /*!< EndPoint RX DISabled */ +#define USB_EP_RX_STALL ((uint16_t)0x1000U) /*!< EndPoint RX STALLed */ +#define USB_EP_RX_NAK ((uint16_t)0x2000U) /*!< EndPoint RX NAKed */ +#define USB_EP_RX_VALID ((uint16_t)0x3000U) /*!< EndPoint RX VALID */ +#define USB_EPRX_DTOG1 ((uint16_t)0x1000U) /*!< EndPoint RX Data TOGgle bit1 */ +#define USB_EPRX_DTOG2 ((uint16_t)0x2000U) /*!< EndPoint RX Data TOGgle bit1 */ +#define USB_EPRX_DTOGMASK (USB_EPRX_STAT|USB_EPREG_MASK) + + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +#if CFG_TUSB_MCU == OPT_MCU_CH32V20X +static const IRQn_Type fsdev_irq[] = { + USB_HP_CAN1_TX_IRQn, + USB_LP_CAN1_RX0_IRQn, + USBWakeUp_IRQn +}; +enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) }; +#else + #error "Unsupported MCU" +#endif + +void dcd_int_enable(uint8_t rhport) { + (void)rhport; + for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) { + NVIC_EnableIRQ(fsdev_irq[i]); + } +} + +void dcd_int_disable(uint8_t rhport) { + (void)rhport; + for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) { + NVIC_DisableIRQ(fsdev_irq[i]); + } +} + +void dcd_disconnect(uint8_t rhport) { + (void) rhport; + EXTEN->EXTEN_CTR &= ~EXTEN_USBD_PU_EN; +} + +void dcd_connect(uint8_t rhport) { + (void) rhport; + EXTEN->EXTEN_CTR |= EXTEN_USBD_PU_EN; +} + +#endif diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h new file mode 100644 index 000000000..af5d8afab --- /dev/null +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -0,0 +1,391 @@ +/* + * The MIT License (MIT) + * + * Copyright(c) 2016 STMicroelectronics + * Copyright(c) N Conrad + * Copyright (c) 2024, hathach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef TUSB_FSDEV_COMMON_H +#define TUSB_FSDEV_COMMON_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "stdint.h" + +// FSDEV_PMA_SIZE is PMA buffer size in bytes. +// On 512-byte devices, access with a stride of two words (use every other 16-bit address) +// On 1024-byte devices, access with a stride of one word (use every 16-bit address) + +// For purposes of accessing the packet +#if ((FSDEV_PMA_SIZE) == 512u) + #define FSDEV_PMA_STRIDE (2u) +#elif ((FSDEV_PMA_SIZE) == 1024u) + #define FSDEV_PMA_STRIDE (1u) +#endif + +// The fsdev_bus_t type can be used for both register and PMA access necessities +// For type-safety create a new macro for the volatile address of PMAADDR +// The compiler should warn us if we cast it to a non-volatile type? +#ifdef FSDEV_BUS_32BIT +typedef uint32_t fsdev_bus_t; +static volatile uint32_t * const pma32 = (volatile uint32_t*)USB_PMAADDR; + +#else +typedef uint16_t fsdev_bus_t; +// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) +static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; + +TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) { + size_t total_word_offset = (((USBx)->BTABLE)>>1) + x; + total_word_offset *= FSDEV_PMA_STRIDE; + return &(pma[total_word_offset]); +} + +TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) { + return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 1u); +} + +TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) { + return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 3u); +} +#endif + +/* Aligned buffer size according to hardware */ +TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t size) { + /* The STM32 full speed USB peripheral supports only a limited set of + * buffer sizes given by the RX buffer entry format in the USB_BTABLE. */ + uint16_t blocksize = (size > 62) ? 32 : 2; + + // Round up while dividing requested size by blocksize + uint16_t numblocks = (size + blocksize - 1) / blocksize ; + + return numblocks * blocksize; +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + volatile uint32_t *reg = (volatile uint32_t *)(USB_DRD_BASE + bEpIdx*4); + *reg = wRegValue; +#else + volatile uint16_t *reg = (volatile uint16_t *)((&USBx->EP0R) + bEpIdx*2u); + *reg = (uint16_t)wRegValue; +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + volatile const uint32_t *reg = (volatile const uint32_t *)(USB_DRD_BASE + bEpIdx*4); +#else + volatile const uint16_t *reg = (volatile const uint16_t *)((&USBx->EP0R) + bEpIdx*2u); +#endif + return *reg; +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= (uint32_t)USB_EP_T_MASK; + regVal |= wType; + regVal |= USB_EP_CTR_RX | USB_EP_CTR_TX; // These clear on write0, so must set high + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_eptype(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EP_T_FIELD; + return regVal; +} + +/** + * @brief Clears bit CTR_RX / CTR_TX in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpIdx Endpoint Number. + * @retval None + */ +TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPREG_MASK; + regVal &= ~USB_EP_CTR_RX; + regVal |= USB_EP_CTR_TX; // preserve CTR_TX (clears on writing 0) + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPREG_MASK; + regVal &= ~USB_EP_CTR_TX; + regVal |= USB_EP_CTR_RX; // preserve CTR_RX (clears on writing 0) + pcd_set_endpoint(USBx, bEpIdx,regVal); +} + +/** + * @brief gets counter of the tx buffer. + * @param USBx USB peripheral instance register address. + * @param bEpIdx Endpoint Number. + * @retval Counter value + */ +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + return (pma32[2*bEpIdx] & 0x03FF0000) >> 16; +#else + volatile const uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpIdx); + return *regPtr & 0x3ffU; +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + return (pma32[2*bEpIdx + 1] & 0x03FF0000) >> 16; +#else + volatile const uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpIdx); + return *regPtr & 0x3ffU; +#endif +} + +#define pcd_get_ep_dbuf0_cnt pcd_get_ep_tx_cnt +#define pcd_get_ep_dbuf1_cnt pcd_get_ep_rx_cnt + +/** + * @brief Sets address in an endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpIdx Endpoint Number. + * @param bAddr Address. + * @retval None + */ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPREG_MASK; + regVal |= bAddr; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpIdx,regVal); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + return pma32[2*bEpIdx] & 0x0000FFFFu ; +#else + return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u); +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + return pma32[2*bEpIdx + 1] & 0x0000FFFFu; +#else + return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u); +#endif +} + +#define pcd_get_ep_dbuf0_address pcd_get_ep_tx_address +#define pcd_get_ep_dbuf1_address pcd_get_ep_rx_address + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + pma32[2*bEpIdx] = (pma32[2*bEpIdx] & 0xFFFF0000u) | (addr & 0x0000FFFCu); +#else + *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u) = addr; +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & 0xFFFF0000u) | (addr & 0x0000FFFCu); +#else + *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u) = addr; +#endif +} + +#define pcd_set_ep_dbuf0_address pcd_set_ep_tx_address +#define pcd_set_ep_dbuf1_address pcd_set_ep_rx_address + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + pma32[2*bEpIdx] = (pma32[2*bEpIdx] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); +#else + volatile uint16_t * reg = pcd_ep_tx_cnt_ptr(USBx, bEpIdx); + *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); +#endif +} + +#define pcd_set_ep_tx_dbuf0_cnt pcd_set_ep_tx_cnt + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_dbuf1_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); +#else + volatile uint16_t * reg = pcd_ep_rx_cnt_ptr(USBx, bEpIdx); + *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDef * USBx, uint32_t rxtx_idx, + uint32_t blocksize, uint32_t numblocks) { + /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ +#ifdef FSDEV_BUS_32BIT + (void) USBx; + pma32[rxtx_idx] = (pma32[rxtx_idx] & 0x0000FFFFu) | (blocksize << 31) | ((numblocks - blocksize) << 26); +#else + volatile uint16_t *pdwReg = pcd_btable_word_ptr(USBx, rxtx_idx*2u + 1u); + *pdwReg = (blocksize << 15) | ((numblocks - blocksize) << 10); +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx, uint32_t rxtx_idx, uint32_t wCount) { + wCount = pcd_aligned_buffer_size(wCount); + + /* We assume that the buffer size is already aligned to hardware requirements. */ + uint16_t blocksize = (wCount > 62) ? 1 : 0; + uint16_t numblocks = wCount / (blocksize ? 32 : 2); + + /* There should be no remainder in the above calculation */ + TU_ASSERT((wCount - (numblocks * (blocksize ? 32 : 2))) == 0, /**/); + + /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ + pcd_set_ep_blsize_num_blocks(USBx, rxtx_idx, blocksize, numblocks); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_dbuf0_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { + pcd_set_ep_bufsize(USBx, 2*bEpIdx, wCount); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { + pcd_set_ep_bufsize(USBx, 2*bEpIdx + 1, wCount); +} + +#define pcd_set_ep_rx_dbuf1_cnt pcd_set_ep_rx_cnt + +/** + * @brief sets the status for tx transfer (bits STAT_TX[1:0]). + * @param USBx USB peripheral instance register address. + * @param bEpIdx Endpoint Number. + * @param wState new state + * @retval None + */ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPTX_DTOGMASK; + + /* toggle first bit ? */ + if((USB_EPTX_DTOG1 & (wState))!= 0U) + { + regVal ^= USB_EPTX_DTOG1; + } + /* toggle second bit ? */ + if((USB_EPTX_DTOG2 & ((uint32_t)(wState)))!= 0U) + { + regVal ^= USB_EPTX_DTOG2; + } + + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +/** + * @brief sets the status for rx transfer (bits STAT_TX[1:0]) + * @param USBx USB peripheral instance register address. + * @param bEpIdx Endpoint Number. + * @param wState new state + * @retval None + */ + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPRX_DTOGMASK; + + /* toggle first bit ? */ + if((USB_EPRX_DTOG1 & wState)!= 0U) { + regVal ^= USB_EPRX_DTOG1; + } + /* toggle second bit ? */ + if((USB_EPRX_DTOG2 & wState)!= 0U) { + regVal ^= USB_EPRX_DTOG2; + } + + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + return (regVal & USB_EPRX_STAT) >> (12u); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPREG_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX; + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPREG_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX; + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + if((regVal & USB_EP_DTOG_RX) != 0) { + pcd_rx_dtog(USBx,bEpIdx); + } +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + if((regVal & USB_EP_DTOG_TX) != 0) { + pcd_tx_dtog(USBx,bEpIdx); + } +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal |= USB_EP_KIND; + regVal &= USB_EPREG_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPKIND_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h new file mode 100644 index 000000000..b3fa11b88 --- /dev/null +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -0,0 +1,292 @@ +/* + * The MIT License (MIT) + * + * Copyright(c) N Conrad + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef TUSB_FSDEV_STM32_H +#define TUSB_FSDEV_STM32_H + +#if CFG_TUSB_MCU == OPT_MCU_STM32F0 + #include "stm32f0xx.h" + #define FSDEV_PMA_SIZE (1024u) + // F0x2 models are crystal-less + // All have internal D+ pull-up + // 070RB: 2 x 16 bits/word memory LPM Support, BCD Support + // PMA dedicated to USB (no sharing with CAN) + +#elif CFG_TUSB_MCU == OPT_MCU_STM32F1 + #include "stm32f1xx.h" + #define FSDEV_PMA_SIZE (512u) + // NO internal Pull-ups + // *B, and *C: 2 x 16 bits/word + + // F1 names this differently from the rest + #define USB_CNTR_LPMODE USB_CNTR_LP_MODE + +#elif defined(STM32F302xB) || defined(STM32F302xC) || \ + defined(STM32F303xB) || defined(STM32F303xC) || \ + defined(STM32F373xC) + #include "stm32f3xx.h" + #define FSDEV_PMA_SIZE (512u) + // NO internal Pull-ups + // *B, and *C: 1 x 16 bits/word + // PMA dedicated to USB (no sharing with CAN) + +#elif defined(STM32F302x6) || defined(STM32F302x8) || \ + defined(STM32F302xD) || defined(STM32F302xE) || \ + defined(STM32F303xD) || defined(STM32F303xE) + #include "stm32f3xx.h" + #define FSDEV_PMA_SIZE (1024u) + // NO internal Pull-ups + // *6, *8, *D, and *E: 2 x 16 bits/word LPM Support + // When CAN clock is enabled, USB can use first 768 bytes ONLY. + +#elif CFG_TUSB_MCU == OPT_MCU_STM32L0 + #include "stm32l0xx.h" + #define FSDEV_PMA_SIZE (1024u) + +#elif CFG_TUSB_MCU == OPT_MCU_STM32L1 + #include "stm32l1xx.h" + #define FSDEV_PMA_SIZE (512u) + +#elif CFG_TUSB_MCU == OPT_MCU_STM32G4 + #include "stm32g4xx.h" + #define FSDEV_PMA_SIZE (1024u) + +#elif CFG_TUSB_MCU == OPT_MCU_STM32G0 + #include "stm32g0xx.h" + #define FSDEV_BUS_32BIT + #define FSDEV_PMA_SIZE (2048u) + #undef USB_PMAADDR + #define USB_PMAADDR USB_DRD_PMAADDR + #define USB_TypeDef USB_DRD_TypeDef + #define EP0R CHEP0R + #define USB_EP_CTR_RX USB_EP_VTRX + #define USB_EP_CTR_TX USB_EP_VTTX + #define USB_EP_T_FIELD USB_CHEP_UTYPE + #define USB_EPREG_MASK USB_CHEP_REG_MASK + #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK + #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK + #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 + #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 + #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 + #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 + #define USB_EPRX_STAT USB_CH_RX_VALID + #define USB_EPKIND_MASK USB_EP_KIND_MASK + #define USB USB_DRD_FS + #define USB_CNTR_FRES USB_CNTR_USBRST + #define USB_CNTR_RESUME USB_CNTR_L2RES + #define USB_ISTR_EP_ID USB_ISTR_IDN + #define USB_EPADDR_FIELD USB_CHEP_ADDR + #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY + #define USB_CNTR_FSUSP USB_CNTR_SUSPEN + +#elif CFG_TUSB_MCU == OPT_MCU_STM32H5 + #include "stm32h5xx.h" + #define FSDEV_BUS_32BIT + + #if !defined(USB_DRD_BASE) && defined(USB_DRD_FS_BASE) + #define USB_DRD_BASE USB_DRD_FS_BASE + #endif + + #define FSDEV_PMA_SIZE (2048u) + #undef USB_PMAADDR + #define USB_PMAADDR USB_DRD_PMAADDR + #define USB_TypeDef USB_DRD_TypeDef + #define EP0R CHEP0R + #define USB_EP_CTR_RX USB_EP_VTRX + #define USB_EP_CTR_TX USB_EP_VTTX + #define USB_EP_T_FIELD USB_CHEP_UTYPE + #define USB_EPREG_MASK USB_CHEP_REG_MASK + #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK + #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK + #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 + #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 + #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 + #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 + #define USB_EPRX_STAT USB_CH_RX_VALID + #define USB_EPKIND_MASK USB_EP_KIND_MASK + #define USB USB_DRD_FS + #define USB_CNTR_FRES USB_CNTR_USBRST + #define USB_CNTR_RESUME USB_CNTR_L2RES + #define USB_ISTR_EP_ID USB_ISTR_IDN + #define USB_EPADDR_FIELD USB_CHEP_ADDR + #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY + #define USB_CNTR_FSUSP USB_CNTR_SUSPEN + +#elif CFG_TUSB_MCU == OPT_MCU_STM32WB + #include "stm32wbxx.h" + #define FSDEV_PMA_SIZE (1024u) + /* ST provided header has incorrect value */ + #undef USB_PMAADDR + #define USB_PMAADDR USB1_PMAADDR + +#elif CFG_TUSB_MCU == OPT_MCU_STM32L4 + #include "stm32l4xx.h" + #define FSDEV_PMA_SIZE (1024u) + +#elif CFG_TUSB_MCU == OPT_MCU_STM32L5 + #include "stm32l5xx.h" + #define FSDEV_PMA_SIZE (1024u) + + #ifndef USB_PMAADDR + #define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS)) + #endif + +#else + #error You are using an untested or unimplemented STM32 variant. Please update the driver. + // This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4 +#endif + +// This checks if the device has "LPM" +#if defined(USB_ISTR_L1REQ) +#define USB_ISTR_L1REQ_FORCED (USB_ISTR_L1REQ) +#else +#define USB_ISTR_L1REQ_FORCED ((uint16_t)0x0000U) +#endif + +#define USB_ISTR_ALL_EVENTS (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_WKUP | USB_ISTR_SUSP | \ + USB_ISTR_RESET | USB_ISTR_SOF | USB_ISTR_ESOF | USB_ISTR_L1REQ_FORCED ) + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +#if TU_CHECK_MCU(OPT_MCU_STM32L1) && !defined(USBWakeUp_IRQn) + #define USBWakeUp_IRQn USB_FS_WKUP_IRQn +#endif + +static const IRQn_Type fsdev_irq[] = { + #if TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32L0, OPT_MCU_STM32L4) + USB_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32F1 + USB_HP_CAN1_TX_IRQn, + USB_LP_CAN1_RX0_IRQn, + USBWakeUp_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32F3 + // USB remap handles dcd functions + USB_HP_CAN_TX_IRQn, + USB_LP_CAN_RX0_IRQn, + USBWakeUp_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32G0 + #ifdef STM32G0B0xx + USB_IRQn, + #else + USB_UCPD1_2_IRQn, + #endif + #elif TU_CHECK_MCU(OPT_MCU_STM32G4, OPT_MCU_STM32L1) + USB_HP_IRQn, + USB_LP_IRQn, + USBWakeUp_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32H5 + USB_DRD_FS_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32L5 + USB_FS_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32WB + USB_HP_IRQn, + USB_LP_IRQn, + #else + #error Unknown arch in USB driver + #endif +}; +enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) }; + +void dcd_int_enable(uint8_t rhport) { + (void)rhport; + + // forces write to RAM before allowing ISR to execute + __DSB(); __ISB(); + + #if CFG_TUSB_MCU == OPT_MCU_STM32F3 && defined(SYSCFG_CFGR1_USB_IT_RMP) + // Some STM32F302/F303 devices allow to remap the USB interrupt vectors from + // shared USB/CAN IRQs to separate CAN and USB IRQs. + // This dynamically checks if this remap is active to enable the right IRQs. + if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) { + NVIC_EnableIRQ(USB_HP_IRQn); + NVIC_EnableIRQ(USB_LP_IRQn); + NVIC_EnableIRQ(USBWakeUp_RMP_IRQn); + } else + #endif + { + for (uint8_t i = 0; i < FSDEV_IRQ_NUM; i++) { + NVIC_EnableIRQ(fsdev_irq[i]); + } + } +} + +void dcd_int_disable(uint8_t rhport) { + (void)rhport; + + #if CFG_TUSB_MCU == OPT_MCU_STM32F3 && defined(SYSCFG_CFGR1_USB_IT_RMP) + // Some STM32F302/F303 devices allow to remap the USB interrupt vectors from + // shared USB/CAN IRQs to separate CAN and USB IRQs. + // This dynamically checks if this remap is active to enable the right IRQs. + if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) { + NVIC_DisableIRQ(USB_HP_IRQn); + NVIC_DisableIRQ(USB_LP_IRQn); + NVIC_DisableIRQ(USBWakeUp_RMP_IRQn); + } else + #endif + { + for (uint8_t i = 0; i < FSDEV_IRQ_NUM; i++) { + NVIC_DisableIRQ(fsdev_irq[i]); + } + } + + // CMSIS has a membar after disabling interrupts +} + +// Define only on MCU with internal pull-up. BSP can define on MCU without internal PU. +#if defined(USB_BCDR_DPPU) + +void dcd_disconnect(uint8_t rhport) { + (void)rhport; + USB->BCDR &= ~(USB_BCDR_DPPU); +} + +void dcd_connect(uint8_t rhport) { + (void)rhport; + USB->BCDR |= USB_BCDR_DPPU; +} + +#elif defined(SYSCFG_PMC_USB_PU) // works e.g. on STM32L151 + +void dcd_disconnect(uint8_t rhport) { + (void)rhport; + SYSCFG->PMC &= ~(SYSCFG_PMC_USB_PU); +} + +void dcd_connect(uint8_t rhport) { + (void)rhport; + SYSCFG->PMC |= SYSCFG_PMC_USB_PU; +} +#endif + + +#endif /* TUSB_FSDEV_STM32_H */ diff --git a/src/tusb_option.h b/src/tusb_option.h index d74510b60..674c05e54 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -374,6 +374,15 @@ #define CFG_TUD_INTERFACE_MAX 16 #endif +// default to max hardware endpoint, but can be smaller to save RAM +#ifndef CFG_TUD_ENDPPOINT_MAX + #define CFG_TUD_ENDPPOINT_MAX TUP_DCD_ENDPOINT_MAX +#endif + +#if CFG_TUD_ENDPPOINT_MAX > TUP_DCD_ENDPOINT_MAX + #error "CFG_TUD_ENDPPOINT_MAX must be less than or equal to TUP_DCD_ENDPOINT_MAX" +#endif + // USB 2.0 compliance test mode support #ifndef CFG_TUD_TEST_MODE #define CFG_TUD_TEST_MODE 0 -- cgit v1.3.1 From 937b2eac3605e33887beb3604db72a0069b4fa93 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 May 2024 14:00:02 +0700 Subject: change default clock to 144mhz --- .idea/cmake.xml | 5 +++-- hw/bsp/ch32v20x/system_ch32v20x.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index d96b46853..1502831cd 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -128,12 +128,13 @@ - + - + + \ No newline at end of file diff --git a/hw/bsp/ch32v20x/system_ch32v20x.c b/hw/bsp/ch32v20x/system_ch32v20x.c index 588f3165a..bdc0d498f 100644 --- a/hw/bsp/ch32v20x/system_ch32v20x.c +++ b/hw/bsp/ch32v20x/system_ch32v20x.c @@ -22,9 +22,9 @@ //#define SYSCLK_FREQ_48MHz_HSE 48000000 //#define SYSCLK_FREQ_56MHz_HSE 56000000 //#define SYSCLK_FREQ_72MHz_HSE 72000000 -#define SYSCLK_FREQ_96MHz_HSE 96000000 +// #define SYSCLK_FREQ_96MHz_HSE 96000000 //#define SYSCLK_FREQ_120MHz_HSE 120000000 -//#define SYSCLK_FREQ_144MHz_HSE 144000000 +#define SYSCLK_FREQ_144MHz_HSE 144000000 //#define SYSCLK_FREQ_HSI HSI_VALUE //#define SYSCLK_FREQ_48MHz_HSI 48000000 //#define SYSCLK_FREQ_56MHz_HSI 56000000 -- cgit v1.3.1 From daffb24111c03e3630edf6496ff5bb65c2cf8c28 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 May 2024 14:06:25 +0700 Subject: minor clean up --- .idea/cmake.xml | 4 ++-- src/device/dcd.h | 11 +++-------- src/device/usbd.h | 2 +- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 1502831cd..24d4eafe9 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -128,13 +128,13 @@ - - + + \ No newline at end of file diff --git a/src/device/dcd.h b/src/device/dcd.h index 2d3dafa4c..f6735b077 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_DCD_H_ -#define _TUSB_DCD_H_ +#ifndef TUSB_DCD_H_ +#define TUSB_DCD_H_ #include "common/tusb_common.h" #include "osal/osal.h" @@ -35,11 +35,6 @@ extern "C" { #endif -//--------------------------------------------------------------------+ -// Configuration -//--------------------------------------------------------------------+ - - //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ @@ -251,4 +246,4 @@ TU_ATTR_ALWAYS_INLINE static inline void dcd_event_sof(uint8_t rhport, uint32_t } #endif -#endif /* _TUSB_DCD_H_ */ +#endif diff --git a/src/device/usbd.h b/src/device/usbd.h index cba94fdae..e676006ab 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -60,7 +60,7 @@ void tud_task (void) { // Check if there is pending events need processing by tud_task() bool tud_task_event_ready(void); -#ifndef _TUSB_DCD_H_ +#ifndef TUSB_DCD_H_ extern void dcd_int_handler(uint8_t rhport); #endif -- cgit v1.3.1 From 2c880012f7904cc19c73e4e246214b75e61a44df Mon Sep 17 00:00:00 2001 From: Rbb666 Date: Thu, 23 May 2024 15:48:21 +0800 Subject: [osal]Add usb-device and host macro controls. --- lib/rt-thread/SConscript | 2 ++ lib/rt-thread/tusb_config.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/rt-thread/SConscript b/lib/rt-thread/SConscript index 482f6d7b2..34399fd45 100644 --- a/lib/rt-thread/SConscript +++ b/lib/rt-thread/SConscript @@ -34,6 +34,8 @@ if GetDepend(["PKG_TINYUSB_DEVICE_ENABLE"]): src += ["../../src/class/cdc/cdc_device.c"] if GetDepend(["PKG_TINYUSB_DEVICE_MSC"]): src += ["../../src/class/msc/msc_device.c", "port/msc_device_port.c"] + if GetDepend(["PKG_TINYUSB_DEVICE_HID"]): + src += ["../../src/class/hid/hid_device.c"] # for host stack if GetDepend(["PKG_TINYUSB_HOST_ENABLE"]): diff --git a/lib/rt-thread/tusb_config.h b/lib/rt-thread/tusb_config.h index b3c3bf43f..11dc21983 100644 --- a/lib/rt-thread/tusb_config.h +++ b/lib/rt-thread/tusb_config.h @@ -152,12 +152,12 @@ extern "C" { #define CFG_TUH_ENABLED (0) #endif -#if (PKG_TINYUSB_HOST_PORT == 0) +#if (PKG_TINYUSB_HOST_PORT == 0) && defined(PKG_TINYUSB_HOST_ENABLE) #undef CFG_TUSB_RHPORT0_MODE #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | PKG_TINYUSB_HOST_PORT_SPEED) #endif -#if (PKG_TINYUSB_HOST_PORT == 1) +#if (PKG_TINYUSB_HOST_PORT == 1) && defined(PKG_TINYUSB_HOST_ENABLE) #undef CFG_TUSB_RHPORT1_MODE #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_HOST | PKG_TINYUSB_HOST_PORT_SPEED) #endif -- cgit v1.3.1 From afbb07b472924c3d60431f0949b08a0aff0c02a5 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 May 2024 17:36:17 +0700 Subject: test README.rst --- README.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index dbe75adc8..043095887 100644 --- a/README.rst +++ b/README.rst @@ -122,10 +122,9 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l | GigaDevice | GD32VF103 | +--------------+------------------------------------------------------------+ | Infineon | XMC4500 | -+--------------+-----+------------------------------------------------------+ -| MicroChip | SAM | D11, D21, D51, E5x, G55, L2x, E7x, S7x, V7x | -| +-----+------------------------------------------------------+ -| | PIC | 24, 32mm, 32mk, 32mx, 32mz, dsPIC33 | ++--------------+------------------------------------------------------------+ +| MicroChip | - SAM: D11, D21, D51, E5x, G55, L2x, E7x, S7x, V7x | +| | - PIC: 24, 32mm, 32mk, 32mx, 32mz, dsPIC33 | +--------------+-----+------------------------------------------------------+ | Mind Montion | mm32 | +--------------+------------------------------------------------------------+ -- cgit v1.3.1 From 3175aaa0eb32e334b3b55824e93b647da3b69a44 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 May 2024 20:17:53 +0700 Subject: increase version as pre-releases, still need more clean up before actual relesae --- README.rst | 38 +++++++++++++----------- docs/info/changelog.rst | 66 +++++++++++++++++++++++++++++++++++++++++ docs/reference/dependencies.rst | 32 ++++++++++---------- hw/bsp/ch32v20x/family.c | 2 -- src/tusb_option.h | 8 ++--- tools/gen_doc.py | 4 +-- tools/make_release.py | 3 ++ 7 files changed, 112 insertions(+), 41 deletions(-) diff --git a/README.rst b/README.rst index 043095887..b5f9fc149 100644 --- a/README.rst +++ b/README.rst @@ -123,40 +123,44 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l +--------------+------------------------------------------------------------+ | Infineon | XMC4500 | +--------------+------------------------------------------------------------+ -| MicroChip | - SAM: D11, D21, D51, E5x, G55, L2x, E7x, S7x, V7x | -| | - PIC: 24, 32mm, 32mk, 32mx, 32mz, dsPIC33 | -+--------------+-----+------------------------------------------------------+ +| | SAM: D11, D21, D51, E5x, G55, L2x, E7x, S7x, V7x | +| MicroChip | | +| | PIC: 24, 32mm, 32mk, 32mx, 32mz, dsPIC33 | ++--------------+------------------------------------------------------------+ | Mind Montion | mm32 | +--------------+------------------------------------------------------------+ | NordicSemi | nRF52833, nRF52840, nRF5340 | +--------------+------------------------------------------------------------+ | Nuvoton | NUC 120, 121, 125, 126, 505 | -+--------------+---------+--------------------------------------------------+ -| NXP | iMXRT | RT10xx, RT11xx | -| +---------+--------------------------------------------------+ -| | Kinetis | KL, K32L2 | -| +---------+--------------------------------------------------+ -| | LPC | 11u, 13, 15, 17, 18, 40, 43, 51u, 54, 55 | -| +---------+--------------------------------------------------+ -| | MCX | A15, N9 | -+--------------+---------+--------------------------------------------------+ ++--------------+------------------------------------------------------------+ +| NXP | iMXRT: RT10xx, RT11xx | +| | | +| | Kinetis: KL, K32L2 | +| | | +| | LPC: 11u, 13, 15, 17, 18, 40, 43, 51u, 54, 55 | +| | | +| | MCX: A15, N9 | ++--------------+------------------------------------------------------------+ | Raspberry Pi | RP2040 | +--------------+-----+------------------------------------------------------+ -| Renesas | RX | 63N, 65N, 72N | -+--------------+-----+------------------------------------------------------+ -| | RA | 4M1, 4M3, 6M1, 6M5 | +| Renesas | RA: 4M1, 4M3, 6M1, 6M5 | +| | | +| | RX: 63N, 65N, 72N | +--------------+-----+------------------------------------------------------+ | Silabs | EFM32GG12 | +--------------+------------------------------------------------------------+ | Sony | CXD56 | +--------------+------------------------------------------------------------+ -| ST STM32 | F0, F1, F2, F3, F4, F7, H7, G0, G4, L0, L1, L4, L4+ U5, WB | +| ST STM32 | F0, F1, F2, F3, F4, F7, H5, H7, G0, G4, L0, L1, L4, L4+, | +| | U5, WB | +--------------+------------------------------------------------------------+ | TI | MSP430, MSP432E4, TM4C123 | +--------------+------------------------------------------------------------+ | ValentyUSB | eptri | +--------------+------------------------------------------------------------+ -| WCH | CH32F20x, CH32V20x, CH32V307 | +| WCH | CH32F: F20x | +| | | +| | CH32V: V20x, V307 | +--------------+------------------------------------------------------------+ License diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index b359ebb44..f7ccb39b9 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -2,6 +2,72 @@ Changelog ********* +0.17.0 (WIP) +============ + +General +------- + +- Improved continuous integration: build both cmake and make. Make use of circleci to build arm-clang + + +Controller Driver (DCD & HCD) +----------------------------- + +- WCH CH32 + + - Added support for USB OTG/FS and FSDev Driver. Update CH32V307 to allow manual select FS or HS driver. + - Fixed various bugs in CH32v307 usbhs driver: endpoint handling and data transfer management. + +- Fixed race conditions and other bugs in dcd_nrf5x and other drivers. +- Implemented hcd abort transfer for Max3421 and rp2040 +- Added DWC2 Test Mode support. +- stm32 fsdev: ISO EP buffer allocation improvements, implement dcd_edpt_close_all() +- Added support for STM32G4 and STM32U5 microcontrollers. + +Device Stack +------------ + +- Added tud_deinit() to deinitialize TinyUSB device stack. +- Added support for generic SOF callback. + +- Audio + + - Add audio_test_freertos & audio_4_channel_mic_freertos + - Improved support for Audio Class 2.0 (UAC2) with various bug fixes. + +- HID + + - Added missing key codes for keypad + - Added HID Lighting and Illumination functionality + +- Vendor: Added empty transfers for tud_vendor_n_write() +- MSC: Added support for SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL + +- CDC + + - Add option to make CDC TX buffer persistent + - Add missing capability bit for CDC ACM serial break support + +- Net + + - Rewrite of NCM device driver + - removed obsolete tud_network_link_state_cb() + +- Enhanced CDC class with better handling of large data transmissions. +- Fixed issues in the HID class for more reliable device enumeration. +- Video Added support for USB Video Class (UVC) with MJPEG. +- USBTMC Added notification support + +Host Stack +---------- + +- Added tuh_deinit() to deinitialize TinyUSB host stack. +- Added support for new USB mass storage class APIs. +- Enhanced stability of CDC-ACM devices during enumeration. +- Improved error handling and retry mechanisms for unstable devices. +- Added support for multiple interfaces in UVC. + 0.16.0 ====== diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index 3a98594ff..fd895519e 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -4,21 +4,21 @@ Dependencies MCU low-level peripheral driver and external libraries for building TinyUSB examples -======================================== ============================================================== ======================================== ======================================================================================================================================================================================================= +======================================== ============================================================== ======================================== ========================================================================================================================================================================================================================================================================================================================== Local Path Repo Commit Required by -======================================== ============================================================== ======================================== ======================================================================================================================================================================================================= +======================================== ============================================================== ======================================== ========================================================================================================================================================================================================================================================================================================================== hw/mcu/allwinner https://github.com/hathach/allwinner_driver.git 8e5e89e8e132c0fd90e72d5422e5d3d68232b756 fc100s hw/mcu/bridgetek/ft9xx/ft90x-sdk https://github.com/BRTSG-FOSS/ft90x-sdk.git 91060164afe239fcb394122e8bf9eb24d3194eb1 brtmm90x hw/mcu/broadcom https://github.com/adafruit/broadcom-peripherals.git 08370086080759ed54ac1136d62d2ad24c6fa267 broadcom_32bit broadcom_64bit hw/mcu/gd/nuclei-sdk https://github.com/Nuclei-Software/nuclei-sdk.git 7eb7bfa9ea4fbeacfafe1d5f77d5a0e6ed3922e7 gd32vf103 hw/mcu/infineon/mtb-xmclib-cat3 https://github.com/Infineon/mtb-xmclib-cat3.git daf5500d03cba23e68c2f241c30af79cd9d63880 xmc4000 -hw/mcu/microchip https://github.com/hathach/microchip_driver.git 9e8b37e307d8404033bb881623a113931e1edf27 sam3x samd11 samd21 samd51 same5x same7x saml2x samg -hw/mcu/mindmotion/mm32sdk https://github.com/hathach/mm32sdk.git 0b79559eb411149d36e073c1635c620e576308d4 mm32 -hw/mcu/nordic/nrfx https://github.com/NordicSemiconductor/nrfx.git 2527e3c8449cfd38aee41598e8af8492f410ed15 nrf +hw/mcu/microchip https://github.com/hathach/microchip_driver.git 9e8b37e307d8404033bb881623a113931e1edf27 sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg +hw/mcu/mindmotion/mm32sdk https://github.com/hathach/mm32sdk.git b93e856211060ae825216c6a1d6aa347ec758843 mm32 +hw/mcu/nordic/nrfx https://github.com/NordicSemiconductor/nrfx.git 7c47cc0a56ce44658e6da2458e86cd8783ccc4a2 nrf hw/mcu/nuvoton https://github.com/majbthrd/nuc_driver.git 2204191ec76283371419fbcec207da02e1bc22fa nuc -hw/mcu/nxp/lpcopen https://github.com/hathach/nxp_lpcopen.git 84e0bd3e43910aaf71eefd62075cf57495418312 lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 -hw/mcu/nxp/mcux-sdk https://github.com/hathach/mcux-sdk.git 950819b7de9b32f92c3edf396bc5ffb8d66e7009 kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx imxrt -hw/mcu/raspberry_pi/Pico-PIO-USB https://github.com/sekigon-gonnoc/Pico-PIO-USB.git d00a10a8c425d0d40f81b87169102944b01f3bb3 rp2040 +hw/mcu/nxp/lpcopen https://github.com/hathach/nxp_lpcopen.git 04bfe7a5f6ee74a89a28ad618d3367dcfcfb7d83 lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 +hw/mcu/nxp/mcux-sdk https://github.com/hathach/mcux-sdk.git 144f1eb7ea8c06512e12f12b27383601c0272410 kinetis_k kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx imxrt +hw/mcu/raspberry_pi/Pico-PIO-USB https://github.com/sekigon-gonnoc/Pico-PIO-USB.git 0f747aaa0c16f750bdfa2ba37ec25d6c8e1bc117 rp2040 hw/mcu/renesas/fsp https://github.com/renesas/fsp.git d52e5a6a59b7c638da860c2bb309b6e78e752ff8 ra hw/mcu/renesas/rx https://github.com/kkitayam/rx_device.git 706b4e0cf485605c32351e2f90f5698267996023 rx hw/mcu/silabs/cmsis-dfp-efm32gg12b https://github.com/cmsis-packs/cmsis-dfp-efm32gg12b.git f1c31b7887669cb230b3ea63f9b56769078960bc efm32 @@ -28,15 +28,16 @@ hw/mcu/st/cmsis_device_f1 https://github.com/STMicroelectronics/ hw/mcu/st/cmsis_device_f2 https://github.com/STMicroelectronics/cmsis_device_f2.git 182fcb3681ce116816feb41b7764f1b019ce796f stm32f2 hw/mcu/st/cmsis_device_f3 https://github.com/STMicroelectronics/cmsis_device_f3.git 5e4ee5ed7a7b6c85176bb70a9fd3c72d6eb99f1b stm32f3 hw/mcu/st/cmsis_device_f4 https://github.com/STMicroelectronics/cmsis_device_f4.git 2615e866fa48fe1ff1af9e31c348813f2b19e7ec stm32f4 -hw/mcu/st/cmsis_device_f7 https://github.com/STMicroelectronics/cmsis_device_f7.git fc676ef1ad177eb874eaa06444d3d75395fc51f4 stm32f7 +hw/mcu/st/cmsis_device_f7 https://github.com/STMicroelectronics/cmsis_device_f7.git 25b0463439303b7a38f0d27b161f7d2f3c096e79 stm32f7 hw/mcu/st/cmsis_device_g0 https://github.com/STMicroelectronics/cmsis_device_g0.git 3a23e1224417f3f2d00300ecd620495e363f2094 stm32g0 hw/mcu/st/cmsis_device_g4 https://github.com/STMicroelectronics/cmsis_device_g4.git ce822adb1dc552b3aedd13621edbc7fdae124878 stm32g4 +hw/mcu/st/cmsis_device_h5 https://github.com/STMicroelectronics/cmsis_device_h5.git cd2d1d579743de57b88ccaf61a968b9c05848ffc stm32h5 hw/mcu/st/cmsis_device_h7 https://github.com/STMicroelectronics/cmsis_device_h7.git 60dc2c913203dc8629dc233d4384dcc41c91e77f stm32h7 -hw/mcu/st/cmsis_device_l0 https://github.com/STMicroelectronics/cmsis_device_l0.git 06748ca1f93827befdb8b794402320d94d02004f stm32l0 +hw/mcu/st/cmsis_device_l0 https://github.com/STMicroelectronics/cmsis_device_l0.git 69cd5999fd40ae6e546d4905b21635c6ca1bcb92 stm32l0 hw/mcu/st/cmsis_device_l1 https://github.com/STMicroelectronics/cmsis_device_l1.git 7f16ec0a1c4c063f84160b4cc6bf88ad554a823e stm32l1 hw/mcu/st/cmsis_device_l4 https://github.com/STMicroelectronics/cmsis_device_l4.git 6ca7312fa6a5a460b5a5a63d66da527fdd8359a6 stm32l4 hw/mcu/st/cmsis_device_l5 https://github.com/STMicroelectronics/cmsis_device_l5.git d922865fc0326a102c26211c44b8e42f52c1e53d stm32l5 -hw/mcu/st/cmsis_device_u5 https://github.com/STMicroelectronics/cmsis_device_u5.git 06d7edade7167b0eafdd550bf77cfc4fa98eae2e stm32u5 +hw/mcu/st/cmsis_device_u5 https://github.com/STMicroelectronics/cmsis_device_u5.git 5ad9797c54ec3e55eff770fc9b3cd4a1aefc1309 stm32u5 hw/mcu/st/cmsis_device_wb https://github.com/STMicroelectronics/cmsis_device_wb.git 9c5d1920dd9fabbe2548e10561d63db829bb744f stm32wb hw/mcu/st/stm32f0xx_hal_driver https://github.com/STMicroelectronics/stm32f0xx_hal_driver.git 0e95cd88657030f640a11e690a8a5186c7712ea5 stm32f0 hw/mcu/st/stm32f1xx_hal_driver https://github.com/STMicroelectronics/stm32f1xx_hal_driver.git 1dd9d3662fb7eb2a7f7d3bc0a4c1dc7537915a29 stm32f1 @@ -46,6 +47,7 @@ hw/mcu/st/stm32f4xx_hal_driver https://github.com/STMicroelectronics/ hw/mcu/st/stm32f7xx_hal_driver https://github.com/STMicroelectronics/stm32f7xx_hal_driver.git f7ffdf6bf72110e58b42c632b0a051df5997e4ee stm32f7 hw/mcu/st/stm32g0xx_hal_driver https://github.com/STMicroelectronics/stm32g0xx_hal_driver.git e911b12c7f67084d7f6b76157a4c0d4e2ec3779c stm32g0 hw/mcu/st/stm32g4xx_hal_driver https://github.com/STMicroelectronics/stm32g4xx_hal_driver.git 8b4518417706d42eef5c14e56a650005abf478a8 stm32g4 +hw/mcu/st/stm32h5xx_hal_driver https://github.com/STMicroelectronics/stm32h5xx_hal_driver.git 2cf77de584196d619cec1b4586c3b9e2820a254e stm32h5 hw/mcu/st/stm32h7xx_hal_driver https://github.com/STMicroelectronics/stm32h7xx_hal_driver.git d8461b980b59b1625207d8c4f2ce0a9c2a7a3b04 stm32h7 hw/mcu/st/stm32l0xx_hal_driver https://github.com/STMicroelectronics/stm32l0xx_hal_driver.git fbdacaf6f8c82a4e1eb9bd74ba650b491e97e17b stm32l0 hw/mcu/st/stm32l1xx_hal_driver https://github.com/STMicroelectronics/stm32l1xx_hal_driver.git 44efc446fa69ed8344e7fd966e68ed11043b35d9 stm32l1 @@ -53,13 +55,13 @@ hw/mcu/st/stm32l4xx_hal_driver https://github.com/STMicroelectronics/ hw/mcu/st/stm32l5xx_hal_driver https://github.com/STMicroelectronics/stm32l5xx_hal_driver.git 675c32a75df37f39d50d61f51cb0dcf53f07e1cb stm32l5 hw/mcu/st/stm32u5xx_hal_driver https://github.com/STMicroelectronics/stm32u5xx_hal_driver.git 4d93097a67928e9377e655ddd14622adc31b9770 stm32u5 hw/mcu/st/stm32wbxx_hal_driver https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git 2c5f06638be516c1b772f768456ba637f077bac8 stm32wb -hw/mcu/ti https://github.com/hathach/ti_driver.git 143ed6cc20a7615d042b03b21e070197d473e6e5 msp430 msp432e4 tm4c123 +hw/mcu/ti https://github.com/hathach/ti_driver.git 143ed6cc20a7615d042b03b21e070197d473e6e5 msp430 msp432e4 tm4c hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.git 77c4095087e5ed2c548ec9058e655d0b8757663b ch32f20x hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git de6d68c654340d7f27b00cebbfc9aa2740a1abc2 ch32v20x hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 17761f5cf9dbbf2dcf665b7c04934188add20082 ch32v307 -lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 20285262657d1b482d132d20d755c8c330d55c1f imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf ra saml2xstm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wb -lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git 4ff01a7a4a51f53b44496aefee1e3c0071b7b173 all +lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 20285262657d1b482d132d20d755c8c330d55c1f imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf ra saml2xlpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wbsam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samgtm4c +lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git cc0e0707c0c748713485b870bb980852b210877f all lib/lwip https://github.com/lwip-tcpip/lwip.git 159e31b689577dbf69cf0683bbaffbd71fa5ee10 all lib/sct_neopixel https://github.com/gsteiert/sct_neopixel.git e73e04ca63495672d955f9268e003cffe168fcd8 lpc55 tools/uf2 https://github.com/microsoft/uf2.git 19615407727073e36d81bf239c52108ba92e7660 all -======================================== ============================================================== ======================================== ======================================================================================================================================================================================================= +======================================== ============================================================== ======================================== ========================================================================================================================================================================================================================================================================================================================== diff --git a/hw/bsp/ch32v20x/family.c b/hw/bsp/ch32v20x/family.c index a0a8c3f50..be654e543 100644 --- a/hw/bsp/ch32v20x/family.c +++ b/hw/bsp/ch32v20x/family.c @@ -124,8 +124,6 @@ void board_init(void) { __enable_irq(); board_delay(2); - - printf("SystemCoreClock = %ld\r\n", SystemCoreClock); } void board_led_write(bool state) { diff --git a/src/tusb_option.h b/src/tusb_option.h index 674c05e54..db8b94580 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -29,14 +29,12 @@ #include "common/tusb_compiler.h" -// Version is release as major.minor.revision eg 1.0.0. though there could be notable APIs before a new release. -// For notable API changes within a release, we increase the build number. +// Version is release as major.minor.revision eg 1.0.0 #define TUSB_VERSION_MAJOR 0 -#define TUSB_VERSION_MINOR 16 +#define TUSB_VERSION_MINOR 17 #define TUSB_VERSION_REVISION 0 -#define TUSB_VERSION_BUILD 3 -#define TUSB_VERSION_NUMBER (TUSB_VERSION_MAJOR << 24 | TUSB_VERSION_MINOR << 16 | TUSB_VERSION_REVISION << 8 | TUSB_VERSION_BUILD) +#define TUSB_VERSION_NUMBER (TUSB_VERSION_MAJOR * 10000 + TUSB_VERSION_MINOR * 100 + TUSB_VERSION_REVISION) #define TUSB_VERSION_STRING TU_STRING(TUSB_VERSION_MAJOR) "." TU_STRING(TUSB_VERSION_MINOR) "." TU_STRING(TUSB_VERSION_REVISION) //--------------------------------------------------------------------+ diff --git a/tools/gen_doc.py b/tools/gen_doc.py index c63294588..668c77ef6 100644 --- a/tools/gen_doc.py +++ b/tools/gen_doc.py @@ -7,9 +7,9 @@ from get_deps import deps_all TOP = Path(__file__).parent.parent.resolve() -########################################### +# ----------------------------------------- # Dependencies -########################################### +# ----------------------------------------- def gen_deps_doc(): deps_rst = Path(TOP) / "docs/reference/dependencies.rst" diff --git a/tools/make_release.py b/tools/make_release.py index 256ca8f21..126e07292 100644 --- a/tools/make_release.py +++ b/tools/make_release.py @@ -1,4 +1,5 @@ import re +import gen_doc version = '0.16.0' @@ -46,4 +47,6 @@ with open(f_library_json, 'w') as f: # docs/info/changelog.rst ################### +gen_doc.gen_deps_doc() + print("Update docs/info/changelog.rst") -- cgit v1.3.1 From a2e5ea1882f130ee22eedbb68296b4b5ce561f77 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Wed, 15 May 2024 21:23:39 +1000 Subject: chipidea/mimxrt: Add support for dcd_sof_enable(). --- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index f9ec666e5..93e1d78dd 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -309,10 +309,12 @@ void dcd_disconnect(uint8_t rhport) void dcd_sof_enable(uint8_t rhport, bool en) { - (void) rhport; - (void) en; - - // TODO implement later + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + if (en) { + dcd_reg->USBINTR |= INTR_SOF; + } else { + dcd_reg->USBINTR &= ~INTR_SOF; + } } //--------------------------------------------------------------------+ @@ -679,7 +681,8 @@ void dcd_int_handler(uint8_t rhport) if (int_status & INTR_SOF) { - dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + const uint32_t frame = dcd_reg->FRINDEX; + dcd_event_sof(rhport, frame, true); } } -- cgit v1.3.1 From e229270a1c3d542cdf9924313f585dd43c607de8 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Thu, 16 May 2024 14:12:22 +1000 Subject: microchip samd: Add support for dcd_sof_enable(). --- src/portable/microchip/samd/dcd_samd.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c index 976d3dfd0..005b63faf 100644 --- a/src/portable/microchip/samd/dcd_samd.c +++ b/src/portable/microchip/samd/dcd_samd.c @@ -183,9 +183,12 @@ void dcd_connect(uint8_t rhport) void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; - (void) en; - // TODO implement later + if (en) { + USB->DEVICE.INTENSET.bit.SOF = 1; + } else { + USB->DEVICE.INTENCLR.bit.SOF = 1; + } } /*------------------------------------------------------------------*/ @@ -374,7 +377,9 @@ void dcd_int_handler (uint8_t rhport) if ( int_status & USB_DEVICE_INTFLAG_SOF ) { USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_SOF; - dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + const uint32_t frame = USB->DEVICE.FNUM.bit.FNUM; + dcd_event_sof(0, frame, true); + //dcd_event_bus_signal(0, DCD_EVENT_SOF, true); } // SAMD doesn't distinguish between Suspend and Disconnect state. -- cgit v1.3.1 From 160cd79fdb9fee70894c4d9bfe908af38b88dc46 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Thu, 16 May 2024 16:05:36 +1000 Subject: nrf5x: Add support for dcd_sof_enable(). --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index bb07063d2..abce35245 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -120,6 +120,9 @@ static struct { // nRF can only carry one DMA at a time, this is used to guard the access to EasyDMA atomic_flag dma_running; + + // Track whether sof has been manually enabled + bool sof_enabled; } _dcd; /*------------------------------------------------------------------*/ @@ -283,9 +286,13 @@ void dcd_connect(uint8_t rhport) { void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; - (void) en; - - // TODO implement later + if (en) { + _dcd.sof_enabled = true; + NRF_USBD->INTENSET = USBD_INTENSET_SOF_Msk; + } else { + _dcd.sof_enabled = false; + NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk; + } } //--------------------------------------------------------------------+ @@ -607,13 +614,16 @@ void dcd_int_handler(uint8_t rhport) { } } - if (!iso_enabled) { - // ISO endpoint is not used, SOF is only enabled one-time for remote wakeup - // so we disable it now - NRF_USBD->INTENCLR = USBD_INTENSET_SOF_Msk; + if (!iso_enabled && !_dcd.sof_enabled) { + // SOF interrupt not manually enabled and ISO endpoint is not used, + // SOF is only enabled one-time for remote wakeup so we disable it now + + NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk; } - dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + const uint32_t frame = NRF_USBD->FRAMECNTR; + dcd_event_sof(0, frame, true); + //dcd_event_bus_signal(0, DCD_EVENT_SOF, true); } if (int_status & USBD_INTEN_USBEVENT_Msk) { -- cgit v1.3.1 From 087fe79e2cd8558f62442d530ef23d249112d389 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Sun, 19 May 2024 13:43:30 +1000 Subject: renesas: Add support for dcd_sof_enable(). --- src/portable/renesas/rusb2/dcd_rusb2.c | 40 ++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 50400d1f5..7c6044ca0 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -29,10 +29,6 @@ #if CFG_TUD_ENABLED && defined(TUP_USBIP_RUSB2) -// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) -// We disable SOF for now until needed later on -#define USE_SOF 0 - #include "device/dcd.h" #include "rusb2_type.h" @@ -74,6 +70,8 @@ typedef struct { pipe_state_t pipe[PIPE_COUNT]; uint8_t ep[2][16]; /* a lookup table for a pipe index from an endpoint address */ + // Track whether sof has been manually enabled + bool sof_enabled; } dcd_data_t; static dcd_data_t _dcd; @@ -664,6 +662,10 @@ void dcd_init(uint8_t rhport) rusb2_reg_t* rusb = RUSB2_REG(rhport); rusb2_module_start(rhport, true); +// We disable SOF for now until needed later on. +// Since TinyUSB doesn't use SOF for now, and this interrupt often (1ms interval) +_dcd.sof_enabled = false; + #ifdef RUSB2_SUPPORT_HIGHSPEED if ( rusb2_is_highspeed_rhport(rhport) ) { rusb->SYSCFG_b.HSE = 1; @@ -708,7 +710,7 @@ void dcd_init(uint8_t rhport) rusb->INTSTS0 = 0; rusb->INTENB0 = RUSB2_INTSTS0_VBINT_Msk | RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_BEMP_Msk | - RUSB2_INTSTS0_DVST_Msk | RUSB2_INTSTS0_CTRT_Msk | (USE_SOF ? RUSB2_INTSTS0_SOFR_Msk : 0) | + RUSB2_INTSTS0_DVST_Msk | RUSB2_INTSTS0_CTRT_Msk | (_dcd.sof_enabled ? RUSB2_INTSTS0_SOFR_Msk : 0) | RUSB2_INTSTS0_RESM_Msk; rusb->BEMPENB = 1; rusb->BRDYENB = 1; @@ -756,10 +758,9 @@ void dcd_disconnect(uint8_t rhport) void dcd_sof_enable(uint8_t rhport, bool en) { - (void) rhport; - (void) en; - - // TODO implement later + rusb2_reg_t* rusb = RUSB2_REG(rhport); + _dcd.sof_enabled = en; + rusb->INTENB0_b.SOFE = en ? 1: 0; } //--------------------------------------------------------------------+ @@ -949,18 +950,19 @@ void dcd_int_handler(uint8_t rhport) // Resumed if ( is0 & RUSB2_INTSTS0_RESM_Msk ) { dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); -#if (0 == USE_SOF) - rusb->INTENB0_b.SOFE = 0; -#endif + if (!_dcd.sof_enabled) { + rusb->INTENB0_b.SOFE = 0; + } } // SOF received if ( (is0 & RUSB2_INTSTS0_SOFR_Msk) && rusb->INTENB0_b.SOFE ) { // USBD will exit suspended mode when SOF event is received - dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); -#if (0 == USE_SOF) - rusb->INTENB0_b.SOFE = 0; -#endif + const uint32_t frame = rusb->FRMNUM_b.FRNM; + dcd_event_sof(rhport, frame, true); + if (!_dcd.sof_enabled) { + rusb->INTENB0_b.SOFE = 0; + } } // Device state changes @@ -979,9 +981,9 @@ void dcd_int_handler(uint8_t rhport) case RUSB2_INTSTS0_DVSQ_STATE_SUSP2: case RUSB2_INTSTS0_DVSQ_STATE_SUSP3: dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); -#if (0 == USE_SOF) - rusb->INTENB0_b.SOFE = 1; -#endif + if (!_dcd.sof_enabled) { + rusb->INTENB0_b.SOFE = 1; + } default: break; } -- cgit v1.3.1 From 8f0459c89e61dfb50a2da73dd6935f6e317b50ac Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 18 May 2024 23:09:13 +0200 Subject: Fix frame count in tud_sof_cb(). --- src/device/usbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 25d890dc7..0fb0aed4e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1189,7 +1189,7 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) } if (tu_bit_test(_usbd_dev.sof_consumer, SOF_CONSUMER_USER)) { - dcd_event_t const event_sof = {.rhport = event->rhport, .event_id = DCD_EVENT_SOF}; + dcd_event_t const event_sof = {.rhport = event->rhport, .event_id = DCD_EVENT_SOF, .sof.frame_count = event->sof.frame_count}; queue_event(&event_sof, in_isr); } break; -- cgit v1.3.1 From a9745c9818da85a0b31ef04c556530a3bef18ec1 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 18 May 2024 23:10:55 +0200 Subject: Fix tud_sof_cb_enable() return type. --- src/device/usbd.c | 3 +-- src/device/usbd.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 0fb0aed4e..922faf112 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -390,10 +390,9 @@ bool tud_connect(void) { return true; } -bool tud_sof_cb_enable(bool en) +void tud_sof_cb_enable(bool en) { usbd_sof_enable(_usbd_rhport, SOF_CONSUMER_USER, en); - return true; } //--------------------------------------------------------------------+ diff --git a/src/device/usbd.h b/src/device/usbd.h index cba94fdae..e439dd961 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -98,7 +98,7 @@ bool tud_disconnect(void); bool tud_connect(void); // Enable or disable the Start Of Frame callback support -bool tud_sof_cb_enable(bool en); +void tud_sof_cb_enable(bool en); // Carry out Data and Status stage of control transfer // - If len = 0, it is equivalent to sending status only -- cgit v1.3.1 From 8767d1ab7d2a7d3870d9bc6b6624b5f580f63e9d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 May 2024 15:19:59 +0700 Subject: fix xtensa_api.h include --- src/portable/espressif/esp32sx/dcd_esp32sx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/portable/espressif/esp32sx/dcd_esp32sx.c b/src/portable/espressif/esp32sx/dcd_esp32sx.c index bfc0baa56..f912bef89 100644 --- a/src/portable/espressif/esp32sx/dcd_esp32sx.c +++ b/src/portable/espressif/esp32sx/dcd_esp32sx.c @@ -31,7 +31,8 @@ #if (((CFG_TUSB_MCU == OPT_MCU_ESP32S2) || (CFG_TUSB_MCU == OPT_MCU_ESP32S3)) && CFG_TUD_ENABLED) // Espressif -#include "xtensa_api.h" +#include "xtensa/xtensa_api.h" + #include "esp_intr_alloc.h" #include "esp_log.h" #include "soc/dport_reg.h" -- cgit v1.3.1 From 4938128cccd3a76907caf546eacee41e53b989e7 Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 29 May 2024 12:54:15 -0700 Subject: Make it compile for STM32U545. --- src/portable/synopsys/dwc2/dwc2_stm32.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 3237a50f6..9957976a5 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -89,6 +89,12 @@ extern "C" { #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 + #define USB_OTG_FS_IRQN OTG_FS_IRQn + #elif defined(USB_DRD_FS) + #define USB_OTG_FS_PERIPH_BASE USB_DRD_BASE + #define EP_MAX_FS 6 + #define EP_FIFO_SIZE_FS 1280 + #define USB_OTG_FS_IRQN USB_IRQn #else #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE #define EP_MAX_HS 9 @@ -109,7 +115,7 @@ extern "C" { // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { #ifdef USB_OTG_FS_PERIPH_BASE - { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, + { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = USB_OTG_FS_IRQN, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, #endif #ifdef USB_OTG_HS_PERIPH_BASE -- cgit v1.3.1 From 22e6b1130fa60b76ed0a1d9b6cc049179606c48c Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 29 May 2024 13:13:47 -0700 Subject: Cleaner approach. --- src/portable/synopsys/dwc2/dwc2_stm32.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 9957976a5..5743569db 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -84,17 +84,16 @@ extern "C" { #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 #include "stm32u5xx.h" - // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #ifdef USB_OTG_FS #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 - #define USB_OTG_FS_IRQN OTG_FS_IRQn + // U53x/U54x are fullspeed with built-in FS PHY but not OTG #elif defined(USB_DRD_FS) - #define USB_OTG_FS_PERIPH_BASE USB_DRD_BASE + #define USB_DRD_FS_PERIPH_BASE USB_DRD_BASE #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 - #define USB_OTG_FS_IRQN USB_IRQn + // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #else #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE #define EP_MAX_HS 9 @@ -114,6 +113,10 @@ extern "C" { // On STM32 for consistency we associate // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { + #ifdef USB_DRD_FS_PERIPH_BASE + { .reg_base = USB_DRD_FS_PERIPH_BASE, .irqnum = USB_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, + #endif + #ifdef USB_OTG_FS_PERIPH_BASE { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = USB_OTG_FS_IRQN, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, #endif -- cgit v1.3.1 From 2e946ac77a8fda2b4b36c19df5294cd7213d46aa Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 29 May 2024 13:23:18 -0700 Subject: Use correct specs. --- src/portable/synopsys/dwc2/dwc2_stm32.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 5743569db..4f311782d 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -91,8 +91,8 @@ extern "C" { // U53x/U54x are fullspeed with built-in FS PHY but not OTG #elif defined(USB_DRD_FS) #define USB_DRD_FS_PERIPH_BASE USB_DRD_BASE - #define EP_MAX_FS 6 - #define EP_FIFO_SIZE_FS 1280 + #define EP_MAX_FS 8 + #define EP_FIFO_SIZE_FS 2048 // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #else #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE -- cgit v1.3.1 From 60d7fcb1ee8dcc4870221e97c1e3fba5463a9d45 Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Thu, 30 May 2024 13:26:14 -0700 Subject: Use correct backend. --- src/common/tusb_mcu.h | 25 +++++++++++++-------- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 2 +- src/portable/st/stm32_fsdev/fsdev_stm32.h | 31 +++++++++++++++++++++++++++ src/portable/synopsys/dwc2/dwc2_stm32.h | 11 +--------- 4 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index c66996c4f..0f4fca8d1 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -271,17 +271,24 @@ #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32U5) - #define TUP_USBIP_DWC2 - #define TUP_USBIP_DWC2_STM32 + #ifdef USB_DRD_FS + #define TUP_USBIP_FSDEV + #define TUP_USBIP_FSDEV_STM32 + #define TUP_DCD_ENDPOINT_MAX 8 - // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY - #if defined(STM32U595xx) || defined(STM32U599xx) || defined(STM32U5A5xx) || defined(STM32U5A9xx) || \ - defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) - #define TUP_DCD_ENDPOINT_MAX 9 - #define TUP_RHPORT_HIGHSPEED 1 - #define TUP_USBIP_DWC2_TEST_MODE #else - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_STM32 + + // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY + #if defined(STM32U595xx) || defined(STM32U599xx) || defined(STM32U5A5xx) || defined(STM32U5A9xx) || \ + defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) + #define TUP_DCD_ENDPOINT_MAX 9 + #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_USBIP_DWC2_TEST_MODE + #else + #define TUP_DCD_ENDPOINT_MAX 6 + #endif #endif #elif TU_CHECK_MCU(OPT_MCU_STM32L5) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 9ce37f992..5f230d86f 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -232,7 +232,7 @@ void dcd_init(uint8_t rhport) } USB->CNTR = 0; // Enable USB -#if !defined(STM32G0) && !defined(STM32H5) // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address +#if !defined(STM32G0) && !defined(STM32H5) && !defined(STM32U5) // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address USB->BTABLE = DCD_STM32_BTABLE_BASE; #endif USB->ISTR = 0; // Clear pending interrupts diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index b3fa11b88..a5199c9e3 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -159,6 +159,35 @@ #define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS)) #endif +#elif CFG_TUSB_MCU == OPT_MCU_STM32U5 + #include "stm32u5xx.h" + #define FSDEV_BUS_32BIT + + #define FSDEV_PMA_SIZE (2048u) + #undef USB_PMAADDR + #define USB_PMAADDR USB_DRD_PMAADDR + #define USB_TypeDef USB_DRD_TypeDef + #define EP0R CHEP0R + #define USB_EP_CTR_RX USB_EP_VTRX + #define USB_EP_CTR_TX USB_EP_VTTX + #define USB_EP_T_FIELD USB_CHEP_UTYPE + #define USB_EPREG_MASK USB_CHEP_REG_MASK + #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK + #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK + #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 + #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 + #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 + #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 + #define USB_EPRX_STAT USB_CH_RX_VALID + #define USB_EPKIND_MASK USB_EP_KIND_MASK + #define USB USB_DRD_FS + #define USB_CNTR_FRES USB_CNTR_USBRST + #define USB_CNTR_RESUME USB_CNTR_L2RES + #define USB_ISTR_EP_ID USB_ISTR_IDN + #define USB_EPADDR_FIELD USB_CHEP_ADDR + #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY + #define USB_CNTR_FSUSP USB_CNTR_SUSPEN + #else #error You are using an untested or unimplemented STM32 variant. Please update the driver. // This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4 @@ -211,6 +240,8 @@ static const IRQn_Type fsdev_irq[] = { #elif CFG_TUSB_MCU == OPT_MCU_STM32WB USB_HP_IRQn, USB_LP_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 + USB_IRQn, #else #error Unknown arch in USB driver #endif diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 4f311782d..eaac2c44b 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -84,16 +84,11 @@ extern "C" { #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 #include "stm32u5xx.h" + // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #ifdef USB_OTG_FS #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 - // U53x/U54x are fullspeed with built-in FS PHY but not OTG - #elif defined(USB_DRD_FS) - #define USB_DRD_FS_PERIPH_BASE USB_DRD_BASE - #define EP_MAX_FS 8 - #define EP_FIFO_SIZE_FS 2048 - // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #else #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE #define EP_MAX_HS 9 @@ -113,10 +108,6 @@ extern "C" { // On STM32 for consistency we associate // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { - #ifdef USB_DRD_FS_PERIPH_BASE - { .reg_base = USB_DRD_FS_PERIPH_BASE, .irqnum = USB_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, - #endif - #ifdef USB_OTG_FS_PERIPH_BASE { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = USB_OTG_FS_IRQN, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, #endif -- cgit v1.3.1 From 90deeddf3d371005e4a9244b1abc9cfb9fc1636f Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 6 Jun 2024 15:49:20 +0700 Subject: add c6 devkit, tested with max3421e --- .idea/cmake.xml | 2 +- hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.cmake | 2 + hw/bsp/ch32v20x/family.c | 2 +- hw/bsp/ch32v20x/family.cmake | 4 ++ .../boards/espressif_c6_devkitc/board.cmake | 2 + .../espressif/boards/espressif_c6_devkitc/board.h | 51 ++++++++++++++++++++++ hw/bsp/family_support.cmake | 16 +++++++ tools/get_deps.py | 2 +- 8 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 hw/bsp/espressif/boards/espressif_c6_devkitc/board.cmake create mode 100644 hw/bsp/espressif/boards/espressif_c6_devkitc/board.h diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 24d4eafe9..5568609dd 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -131,7 +131,7 @@ - + diff --git a/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.cmake b/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.cmake index 8d3e0326e..31b6b716e 100644 --- a/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.cmake +++ b/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.cmake @@ -3,6 +3,8 @@ set(MCU_VARIANT D6) set(LD_FLASH_SIZE 64K) set(LD_RAM_SIZE 20K) +# set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${CH32_FAMILY}_tinyuf2.ld) + function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CFG_EXAMPLE_MSC_DUAL_READONLY diff --git a/hw/bsp/ch32v20x/family.c b/hw/bsp/ch32v20x/family.c index be654e543..c32cfd46e 100644 --- a/hw/bsp/ch32v20x/family.c +++ b/hw/bsp/ch32v20x/family.c @@ -127,7 +127,7 @@ void board_init(void) { } void board_led_write(bool state) { - GPIO_WriteBit(LED_PORT, LED_PIN, state); + GPIO_WriteBit(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); } uint32_t board_button_read(void) { diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake index 3fb1c0e79..1d574fdf8 100644 --- a/hw/bsp/ch32v20x/family.cmake +++ b/hw/bsp/ch32v20x/family.cmake @@ -1,5 +1,6 @@ include_guard() +set(UF2_FAMILY_ID 0x699b62ec) set(CH32_FAMILY ch32v20x) set(SDK_DIR ${TOP}/hw/mcu/wch/${CH32_FAMILY}) set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) @@ -128,4 +129,7 @@ function(family_configure_example TARGET RTOS) # Flashing family_add_bin_hex(${TARGET}) family_flash_openocd_wch(${TARGET}) + + #family_add_uf2(${TARGET} ${UF2_FAMILY_ID}) + #family_flash_uf2(${TARGET} ${UF2_FAMILY_ID}) endfunction() diff --git a/hw/bsp/espressif/boards/espressif_c6_devkitc/board.cmake b/hw/bsp/espressif/boards/espressif_c6_devkitc/board.cmake new file mode 100644 index 000000000..50c7cb35d --- /dev/null +++ b/hw/bsp/espressif/boards/espressif_c6_devkitc/board.cmake @@ -0,0 +1,2 @@ +# Apply board specific content here +set(IDF_TARGET "esp32c6") diff --git a/hw/bsp/espressif/boards/espressif_c6_devkitc/board.h b/hw/bsp/espressif/boards/espressif_c6_devkitc/board.h new file mode 100644 index 000000000..243dd47f6 --- /dev/null +++ b/hw/bsp/espressif/boards/espressif_c6_devkitc/board.h @@ -0,0 +1,51 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define NEOPIXEL_PIN 8 + +#define BUTTON_PIN 9 +#define BUTTON_STATE_ACTIVE 0 + +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI2_HOST +#define MAX3421_SCK_PIN 4 +#define MAX3421_MOSI_PIN 6 +#define MAX3421_MISO_PIN 5 +#define MAX3421_CS_PIN 10 +#define MAX3421_INTR_PIN 7 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 6eef5b88b..d9443f811 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -6,6 +6,8 @@ include(CMakePrintHelpers) set(TOP "${CMAKE_CURRENT_LIST_DIR}/../..") get_filename_component(TOP ${TOP} ABSOLUTE) +set(UF2CONV_PY ${TOP}/tools/uf2/utils/uf2conv.py) + #------------------------------------------------------------- # Toolchain # Can be changed via -DTOOLCHAIN=gcc|iar or -DCMAKE_C_COMPILER= @@ -296,6 +298,13 @@ function(family_add_bin_hex TARGET) VERBATIM) endfunction() +# Add uf2 output +function(family_add_uf2 TARGET FAMILY_ID) + set(BIN_FILE $/${TARGET}.hex) + add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND python ${UF2CONV_PY} -f ${FAMILY_ID} -c -o $/${TARGET}.uf2 ${BIN_FILE} + VERBATIM) +endfunction() #---------------------------------- # Example Target Configure (Default rule) @@ -461,6 +470,13 @@ function(family_flash_pyocd TARGET) ) endfunction() +# Flash with UF2 +function(family_flash_uf2 TARGET FAMILY_ID) + add_custom_target(${TARGET}-uf2 + DEPENDS ${TARGET} + COMMAND python ${UF2CONV_PY} -f ${FAMILY_ID} --deploy $/${TARGET}.uf2 + ) +endfunction() # Add flash teensy_cli target function(family_flash_teensy TARGET) diff --git a/tools/get_deps.py b/tools/get_deps.py index cf15126b3..50cc5c893 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -14,7 +14,7 @@ deps_mandatory = { '159e31b689577dbf69cf0683bbaffbd71fa5ee10', 'all'], 'tools/uf2': ['https://github.com/microsoft/uf2.git', - '19615407727073e36d81bf239c52108ba92e7660', + 'c594542b2faa01cc33a2b97c9fbebc38549df80a', 'all'], } -- cgit v1.3.1 From 302445e64fec763cfb488f0400ec3cb95e984409 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 6 Jun 2024 16:07:11 +0700 Subject: try to build rx using build_util --- .github/actions/setup_toolchain/download/action.yml | 8 +++++++- .github/workflows/build.yml | 14 +++++++++----- .github/workflows/build_renesas.yml | 1 + .github/workflows/ci_set_matrix.py | 4 +++- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/.github/actions/setup_toolchain/download/action.yml b/.github/actions/setup_toolchain/download/action.yml index 2af456ef8..38f327ec5 100644 --- a/.github/actions/setup_toolchain/download/action.yml +++ b/.github/actions/setup_toolchain/download/action.yml @@ -24,7 +24,13 @@ runs: run: | mkdir -p ~/cache/${{ inputs.toolchain }} wget --progress=dot:giga ${{ inputs.toolchain_url }} -O toolchain.tar.gz - tar -C ~/cache/${{ inputs.toolchain }} -xaf toolchain.tar.gz + if [[ ${{ inputs.toolchain }} == rx-gcc ]]; then + mv toolchain.tar.gz toolchain.run + chmod +x toolchain.run + ./toolchain.run -p ~/cache/${{ inputs.toolchain }} -y + else + tar -C ~/cache/${{ inputs.toolchain }} -xaf toolchain.tar.gz + endif shell: bash - name: Set Toolchain Path diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 78d95fbbc..1c0ca104a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,6 +51,7 @@ jobs: # Build CMake # --------------------------------------- cmake: + if: false needs: set-matrix uses: ./.github/workflows/build_util.yml strategy: @@ -58,7 +59,7 @@ jobs: matrix: toolchain: - 'aarch64-gcc' - # - 'arm-clang' # clang is built by circle-ci + # - 'arm-clang' is built by circle-ci - 'arm-gcc' - 'msp430-gcc' - 'riscv-gcc' @@ -73,7 +74,7 @@ jobs: # Build Make # --------------------------------------- make: - #if: github.event_name == 'pull_request' + # if: false needs: set-matrix uses: ./.github/workflows/build_util.yml strategy: @@ -81,10 +82,11 @@ jobs: matrix: toolchain: - 'aarch64-gcc' - # - 'arm-clang' # clang is built by circle-ci - - 'arm-gcc' + # 'arm-clang' is built by circle-ci + #- 'arm-gcc' - 'msp430-gcc' - 'riscv-gcc' + - 'rx-gcc' with: build-system: 'make' toolchain: ${{ matrix.toolchain }} @@ -112,6 +114,7 @@ jobs: # Build Espressif # --------------------------------------- espressif: + if: false uses: ./.github/workflows/build_util.yml strategy: fail-fast: false @@ -131,7 +134,8 @@ jobs: # Build IAR on HFP self-hosted # --------------------------------------- arm-iar: - if: github.repository_owner == 'hathach' + if: false + # if: github.repository_owner == 'hathach' needs: set-matrix runs-on: [self-hosted, Linux, X64, hifiphile] env: diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml index 3d2cbab28..085a1eda7 100644 --- a/.github/workflows/build_renesas.yml +++ b/.github/workflows/build_renesas.yml @@ -26,6 +26,7 @@ concurrency: jobs: build-rx: + if: false runs-on: ubuntu-latest strategy: fail-fast: false diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index c6f4e8fe2..7dc9a2fa1 100644 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -7,7 +7,8 @@ toolchain_list = { "arm-iar": "", "arm-gcc": "", "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", - "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz" + "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz", + "rx-gcc": "http://gcc-renesas.com/downloads/get.php?f=rx/8.3.0.202004-gnurx/gcc-8.3.0.202004-GNURX-ELF.run", } # family: [supported toolchain] @@ -27,6 +28,7 @@ family_list = { "nrf": ["arm-gcc", "arm-clang"], "ra": ["arm-gcc"], "rp2040": ["arm-gcc"], + "rx": ["rx-gcc"], "samd11 samd21 saml2x": ["arm-gcc", "arm-clang"], "samd5x_e5x samg": ["arm-gcc", "arm-clang"], "stm32f0 stm32f1 stm32f2 stm32f3": ["arm-gcc", "arm-clang", "arm-iar"], -- cgit v1.3.1 From 902cc3310b1841159cddd1ac25d17c3ff00c3950 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 6 Jun 2024 16:09:38 +0700 Subject: correct script --- .github/actions/setup_toolchain/download/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/setup_toolchain/download/action.yml b/.github/actions/setup_toolchain/download/action.yml index 38f327ec5..aed614b3c 100644 --- a/.github/actions/setup_toolchain/download/action.yml +++ b/.github/actions/setup_toolchain/download/action.yml @@ -30,7 +30,7 @@ runs: ./toolchain.run -p ~/cache/${{ inputs.toolchain }} -y else tar -C ~/cache/${{ inputs.toolchain }} -xaf toolchain.tar.gz - endif + fi shell: bash - name: Set Toolchain Path -- cgit v1.3.1 From 7771cae94cd1210cd167a4e3e0a654f8a65ab87a Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 6 Jun 2024 16:13:25 +0700 Subject: fix gnurx bin --- .github/actions/setup_toolchain/download/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/setup_toolchain/download/action.yml b/.github/actions/setup_toolchain/download/action.yml index aed614b3c..813197208 100644 --- a/.github/actions/setup_toolchain/download/action.yml +++ b/.github/actions/setup_toolchain/download/action.yml @@ -27,7 +27,7 @@ runs: if [[ ${{ inputs.toolchain }} == rx-gcc ]]; then mv toolchain.tar.gz toolchain.run chmod +x toolchain.run - ./toolchain.run -p ~/cache/${{ inputs.toolchain }} -y + ./toolchain.run -p ~/cache/${{ inputs.toolchain }}/gnurx -y else tar -C ~/cache/${{ inputs.toolchain }} -xaf toolchain.tar.gz fi -- cgit v1.3.1 From 8df372ae7a4c9dfef1d23dc9a4562df482a4d720 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 6 Jun 2024 16:19:02 +0700 Subject: clean up --- .github/workflows/build.yml | 14 ++++---- .github/workflows/build_renesas.yml | 67 ------------------------------------- 2 files changed, 7 insertions(+), 74 deletions(-) delete mode 100644 .github/workflows/build_renesas.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1c0ca104a..712c7dd43 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,15 +51,15 @@ jobs: # Build CMake # --------------------------------------- cmake: - if: false + # if: false needs: set-matrix uses: ./.github/workflows/build_util.yml strategy: fail-fast: false matrix: toolchain: - - 'aarch64-gcc' # - 'arm-clang' is built by circle-ci + - 'aarch64-gcc' - 'arm-gcc' - 'msp430-gcc' - 'riscv-gcc' @@ -81,9 +81,9 @@ jobs: fail-fast: false matrix: toolchain: - - 'aarch64-gcc' # 'arm-clang' is built by circle-ci - #- 'arm-gcc' + - 'aarch64-gcc' + - 'arm-gcc' - 'msp430-gcc' - 'riscv-gcc' - 'rx-gcc' @@ -114,7 +114,7 @@ jobs: # Build Espressif # --------------------------------------- espressif: - if: false + # if: false uses: ./.github/workflows/build_util.yml strategy: fail-fast: false @@ -134,8 +134,8 @@ jobs: # Build IAR on HFP self-hosted # --------------------------------------- arm-iar: - if: false - # if: github.repository_owner == 'hathach' + # if: false + if: github.repository_owner == 'hathach' needs: set-matrix runs-on: [self-hosted, Linux, X64, hifiphile] env: diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml deleted file mode 100644 index 085a1eda7..000000000 --- a/.github/workflows/build_renesas.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: Build Renesas - -on: - workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'tools/get_deps.py' - - '.github/workflows/build_renesas.yml' - pull_request: - branches: [ master ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'tools/get_deps.py' - - '.github/workflows/build_renesas.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - build-rx: - if: false - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - family: - # Alphabetical order - - 'rx' - steps: - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Set Toolchain URL - run: echo >> $GITHUB_ENV TOOLCHAIN_URL=http://gcc-renesas.com/downloads/get.php?f=rx/8.3.0.202004-gnurx/gcc-8.3.0.202004-GNURX-ELF.run - - - name: Cache Toolchain - uses: actions/cache@v4 - id: cache-toolchain - with: - path: ~/cache/ - key: ${{ runner.os }}-21-03-30-${{ env.TOOLCHAIN_URL }} - - - name: Install Toolchain - if: steps.cache-toolchain.outputs.cache-hit != 'true' - run: | - mkdir -p ~/cache/toolchain/gnurx - wget --progress=dot:mega $TOOLCHAIN_URL -O toolchain.run - chmod +x toolchain.run - ./toolchain.run -p ~/cache/toolchain/gnurx -y - - - name: Set Toolchain Path - run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` - - - name: Get Dependencies - run: | - python3 tools/get_deps.py ${{ matrix.family }} - - - name: Build - run: python3 tools/build.py -s make ${{ matrix.family }} -- cgit v1.3.1 From 28c243337591f0ac7745f11737d907d47f0e6320 Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 12 Jun 2024 08:08:25 -0700 Subject: Add stm32u545nucleo board. --- hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk | 1 + hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk | 1 + hw/bsp/stm32u5/family.c | 17 ++++++++++++++++- hw/bsp/stm32u5/family.cmake | 14 ++++++++++---- hw/bsp/stm32u5/family.mk | 14 ++++++++++++-- src/portable/synopsys/dwc2/dwc2_stm32.h | 2 +- 6 files changed, 41 insertions(+), 8 deletions(-) diff --git a/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk b/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk index 1dd157a68..c83ec3999 100644 --- a/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk +++ b/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk @@ -6,5 +6,6 @@ LD_FILE = ${FAMILY_PATH}/linker/STM32U575xx_FLASH.ld SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u575xx.s +MCU_VARIANT = stm32u575xx # For flash-jlink target JLINK_DEVICE = stm32u575zi diff --git a/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk index e759cec24..4bebe3330 100644 --- a/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk +++ b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk @@ -7,5 +7,6 @@ LD_FILE = ${BOARD_PATH}/STM32U5A5ZJTXQ_FLASH.ld SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u5a5xx.s +MCU_VARIANT = stm32u5a5xx # For flash-jlink target JLINK_DEVICE = stm32u575zi diff --git a/hw/bsp/stm32u5/family.c b/hw/bsp/stm32u5/family.c index d779b5c96..0f0868839 100644 --- a/hw/bsp/stm32u5/family.c +++ b/hw/bsp/stm32u5/family.c @@ -72,7 +72,9 @@ void board_init(void) { __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); +#ifdef GPIOF __HAL_RCC_GPIOF_CLK_ENABLE(); +#endif __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); @@ -140,6 +142,17 @@ void board_init(void) { GPIO_InitStruct.Alternate = GPIO_AF10_USB; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); +#ifdef USB_OTG_HS + // STM32U535/STM32U545 + + /* Enable USB power on Pwrctrl CR2 register */ + HAL_PWREx_EnableVddUSB(); + + /* USB clock enable */ + __HAL_RCC_USB_FS_CLK_ENABLE(); + +#endif + #ifdef USB_OTG_FS #if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) @@ -170,7 +183,9 @@ void board_init(void) { /* USB clock enable */ __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); -#else +#endif + +#ifdef USB_OTG_HS // STM59x/Ax/Fx/Gx only have 1 USB HS port #if CFG_TUSB_OS == OPT_OS_FREERTOS diff --git a/hw/bsp/stm32u5/family.cmake b/hw/bsp/stm32u5/family.cmake index 7402540b7..c19bce64b 100644 --- a/hw/bsp/stm32u5/family.cmake +++ b/hw/bsp/stm32u5/family.cmake @@ -102,10 +102,16 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_STM32U5 ${RTOS}) - target_sources(${TARGET}-tinyusb PUBLIC - ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c - #${TOP}/src/portable/st/typec/typec_stm32.c - ) + if ((${MCU_VARIANT} EQUAL "stm32u535xx") OR (${MCU_VARIANT} EQUAL "stm32u545xx")) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c + ) + else () + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c + #${TOP}/src/portable/st/typec/typec_stm32.c + ) + endif () target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) # Link dependencies diff --git a/hw/bsp/stm32u5/family.mk b/hw/bsp/stm32u5/family.mk index be5809340..45f9aa33e 100644 --- a/hw/bsp/stm32u5/family.mk +++ b/hw/bsp/stm32u5/family.mk @@ -27,18 +27,28 @@ LDFLAGS_GCC += \ --specs=nosys.specs --specs=nano.specs SRC_C += \ - src/portable/synopsys/dwc2/dcd_dwc2.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_icache.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_icache.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c +ifeq ($(MCU_VARIANT),stm32u545xx) +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +else ($(MCU_VARIANT),stm32u535xx) +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +else +SRC_C += \ + src/portable/synopsys/dwc2/dcd_dwc2.c +endif + INC += \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index eaac2c44b..3237a50f6 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -109,7 +109,7 @@ extern "C" { // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { #ifdef USB_OTG_FS_PERIPH_BASE - { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = USB_OTG_FS_IRQN, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, + { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, #endif #ifdef USB_OTG_HS_PERIPH_BASE -- cgit v1.3.1 From 6a1dc2507955901ae7d1774cc9ba69230c43485a Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 12 Jun 2024 08:14:06 -0700 Subject: Add missing files. --- hw/bsp/stm32u5/boards/stm32u545nucleo/board.cmake | 8 ++ hw/bsp/stm32u5/boards/stm32u545nucleo/board.h | 112 ++++++++++++++++++++++ hw/bsp/stm32u5/boards/stm32u545nucleo/board.mk | 10 ++ 3 files changed, 130 insertions(+) create mode 100644 hw/bsp/stm32u5/boards/stm32u545nucleo/board.cmake create mode 100644 hw/bsp/stm32u5/boards/stm32u545nucleo/board.h create mode 100644 hw/bsp/stm32u5/boards/stm32u545nucleo/board.mk diff --git a/hw/bsp/stm32u5/boards/stm32u545nucleo/board.cmake b/hw/bsp/stm32u5/boards/stm32u545nucleo/board.cmake new file mode 100644 index 000000000..d42501948 --- /dev/null +++ b/hw/bsp/stm32u5/boards/stm32u545nucleo/board.cmake @@ -0,0 +1,8 @@ +set(MCU_VARIANT stm32u545xx) +set(JLINK_DEVICE stm32u545re) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32U545xx + ) +endfunction() diff --git a/hw/bsp/stm32u5/boards/stm32u545nucleo/board.h b/hw/bsp/stm32u5/boards/stm32u545nucleo/board.h new file mode 100644 index 000000000..6d244d418 --- /dev/null +++ b/hw/bsp/stm32u5/boards/stm32u545nucleo/board.h @@ -0,0 +1,112 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +// LED GREEN +#define LED_PORT GPIOC +#define LED_PIN GPIO_PIN_7 +#define LED_STATE_ON 1 + +// BUTTON +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 1 + +// UART Enable for STLink VCOM +#define UART_DEV LPUART1 +#define UART_CLK_EN __HAL_RCC_LPUART1_CLK_ENABLE +#define UART_GPIO_PORT GPIOG +#define UART_GPIO_AF GPIO_AF8_LPUART1 +#define UART_TX_PIN GPIO_PIN_7 +#define UART_RX_PIN GPIO_PIN_8 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ + +static void SystemClock_Config(void) { + RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; + RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; + RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 }; + + /* Enable Power Clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /** Configure the main internal regulator output voltage + */ + HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSI; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV1; + RCC_OscInitStruct.PLL.PLLM = 1; + RCC_OscInitStruct.PLL.PLLN = 10; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLR = 1; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLLVCIRANGE_1; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_CLK48; + PeriphClkInit.IclkClockSelection = RCC_CLK48CLKSOURCE_HSI48; + + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = + RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_PCLK3; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1; + + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); +} + +static void SystemPower_Config(void) { +} + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/stm32u5/boards/stm32u545nucleo/board.mk b/hw/bsp/stm32u5/boards/stm32u545nucleo/board.mk new file mode 100644 index 000000000..66cba0c2b --- /dev/null +++ b/hw/bsp/stm32u5/boards/stm32u545nucleo/board.mk @@ -0,0 +1,10 @@ +CFLAGS += \ + -DSTM32U545xx \ + +# All source paths should be relative to the top level. +LD_FILE = ${FAMILY_PATH}/linker/STM32U545xx_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u545xx.s + +# For flash-jlink target +JLINK_DEVICE = stm32u545re -- cgit v1.3.1 From bc576e7cee64fedfa977604f8e9e4043b3473ece Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 12 Jun 2024 08:33:10 -0700 Subject: Make it work. --- hw/bsp/stm32u5/boards/stm32u545nucleo/board.mk | 1 + hw/bsp/stm32u5/boards/stm32u575eval/board.mk | 1 + hw/bsp/stm32u5/family.mk | 2 +- src/common/tusb_mcu.h | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/bsp/stm32u5/boards/stm32u545nucleo/board.mk b/hw/bsp/stm32u5/boards/stm32u545nucleo/board.mk index 66cba0c2b..072c595fb 100644 --- a/hw/bsp/stm32u5/boards/stm32u545nucleo/board.mk +++ b/hw/bsp/stm32u5/boards/stm32u545nucleo/board.mk @@ -6,5 +6,6 @@ LD_FILE = ${FAMILY_PATH}/linker/STM32U545xx_FLASH.ld SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u545xx.s +MCU_VARIANT = stm32u545xx # For flash-jlink target JLINK_DEVICE = stm32u545re diff --git a/hw/bsp/stm32u5/boards/stm32u575eval/board.mk b/hw/bsp/stm32u5/boards/stm32u575eval/board.mk index 922d67f83..fee56f2ba 100644 --- a/hw/bsp/stm32u5/boards/stm32u575eval/board.mk +++ b/hw/bsp/stm32u5/boards/stm32u575eval/board.mk @@ -6,5 +6,6 @@ LD_FILE = ${FAMILY_PATH}/linker/STM32U575xx_FLASH.ld SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u575xx.s +MCU_VARIANT = stm32u575xx # For flash-jlink target JLINK_DEVICE = stm32u575ai diff --git a/hw/bsp/stm32u5/family.mk b/hw/bsp/stm32u5/family.mk index 45f9aa33e..9ab8992a8 100644 --- a/hw/bsp/stm32u5/family.mk +++ b/hw/bsp/stm32u5/family.mk @@ -41,7 +41,7 @@ SRC_C += \ ifeq ($(MCU_VARIANT),stm32u545xx) SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c -else ($(MCU_VARIANT),stm32u535xx) +else ifeq ($(MCU_VARIANT),stm32u535xx) SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c else diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 0f4fca8d1..4b802138b 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -271,7 +271,7 @@ #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32U5) - #ifdef USB_DRD_FS + #if defined (STM32U535xx) || defined (STM32U545xx) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define TUP_DCD_ENDPOINT_MAX 8 -- cgit v1.3.1 From 9be10f2adbce72262c56e1f235e58af4cc9d7e40 Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 12 Jun 2024 08:59:43 -0700 Subject: Fix pin definitions. --- hw/bsp/stm32u5/boards/stm32u545nucleo/board.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/hw/bsp/stm32u5/boards/stm32u545nucleo/board.h b/hw/bsp/stm32u5/boards/stm32u545nucleo/board.h index 6d244d418..7f3bf462c 100644 --- a/hw/bsp/stm32u5/boards/stm32u545nucleo/board.h +++ b/hw/bsp/stm32u5/boards/stm32u545nucleo/board.h @@ -33,22 +33,22 @@ extern "C" #endif // LED GREEN -#define LED_PORT GPIOC -#define LED_PIN GPIO_PIN_7 +#define LED_PORT GPIOA +#define LED_PIN GPIO_PIN_5 #define LED_STATE_ON 1 // BUTTON -#define BUTTON_PORT GPIOA -#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 #define BUTTON_STATE_ACTIVE 1 // UART Enable for STLink VCOM #define UART_DEV LPUART1 #define UART_CLK_EN __HAL_RCC_LPUART1_CLK_ENABLE -#define UART_GPIO_PORT GPIOG +#define UART_GPIO_PORT GPIOA #define UART_GPIO_AF GPIO_AF8_LPUART1 -#define UART_TX_PIN GPIO_PIN_7 -#define UART_RX_PIN GPIO_PIN_8 +#define UART_TX_PIN GPIO_PIN_2 +#define UART_RX_PIN GPIO_PIN_3 //--------------------------------------------------------------------+ // RCC Clock -- cgit v1.3.1 From 48e18762b59d71259358e471716e102b2dad4ae3 Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 12 Jun 2024 09:02:48 -0700 Subject: Use correct definition. --- hw/bsp/stm32u5/family.c | 2 +- hw/bsp/stm32u5/family.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/bsp/stm32u5/family.c b/hw/bsp/stm32u5/family.c index 0f0868839..3cc7cc511 100644 --- a/hw/bsp/stm32u5/family.c +++ b/hw/bsp/stm32u5/family.c @@ -142,7 +142,7 @@ void board_init(void) { GPIO_InitStruct.Alternate = GPIO_AF10_USB; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); -#ifdef USB_OTG_HS +#ifdef USB_DRD_FS // STM32U535/STM32U545 /* Enable USB power on Pwrctrl CR2 register */ diff --git a/hw/bsp/stm32u5/family.mk b/hw/bsp/stm32u5/family.mk index 9ab8992a8..89193b99f 100644 --- a/hw/bsp/stm32u5/family.mk +++ b/hw/bsp/stm32u5/family.mk @@ -31,7 +31,7 @@ SRC_C += \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_icache.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_icache.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ -- cgit v1.3.1 From a6d3e2a36d871985020bf3c5f61b84e55eac5589 Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 12 Jun 2024 09:23:18 -0700 Subject: Use STREQUAL instead of EQUAL to fix the cmake build. --- hw/bsp/stm32u5/family.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/bsp/stm32u5/family.cmake b/hw/bsp/stm32u5/family.cmake index c19bce64b..f7a7aeb33 100644 --- a/hw/bsp/stm32u5/family.cmake +++ b/hw/bsp/stm32u5/family.cmake @@ -102,7 +102,7 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_STM32U5 ${RTOS}) - if ((${MCU_VARIANT} EQUAL "stm32u535xx") OR (${MCU_VARIANT} EQUAL "stm32u545xx")) + if ((${MCU_VARIANT} STREQUAL "stm32u535xx") OR (${MCU_VARIANT} STREQUAL "stm32u545xx")) target_sources(${TARGET}-tinyusb PUBLIC ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ) -- cgit v1.3.1 From 2ed027f2bdedae81f20d7417ad7f018a6de9357a Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 12:51:28 +0700 Subject: use stock core_riscv.h for ch32 v2 v3 --- hw/bsp/ch32v20x/core_riscv.h | 572 ------------------------------- hw/bsp/ch32v20x/family.c | 12 + hw/bsp/ch32v20x/family.cmake | 1 + hw/bsp/ch32v20x/family.mk | 4 + hw/bsp/ch32v307/core_riscv.h | 379 -------------------- hw/bsp/ch32v307/debug_uart.c | 9 + hw/bsp/ch32v307/family.c | 13 + hw/bsp/ch32v307/family.cmake | 1 + hw/bsp/ch32v307/family.mk | 4 + src/portable/st/stm32_fsdev/fsdev_ch32.h | 12 +- src/portable/wch/ch32_usbfs_reg.h | 11 + src/portable/wch/ch32_usbhs_reg.h | 12 + 12 files changed, 78 insertions(+), 952 deletions(-) delete mode 100644 hw/bsp/ch32v20x/core_riscv.h delete mode 100644 hw/bsp/ch32v307/core_riscv.h diff --git a/hw/bsp/ch32v20x/core_riscv.h b/hw/bsp/ch32v20x/core_riscv.h deleted file mode 100644 index be1b52a6c..000000000 --- a/hw/bsp/ch32v20x/core_riscv.h +++ /dev/null @@ -1,572 +0,0 @@ -/********************************** (C) COPYRIGHT ******************************* - * File Name : core_riscv.h - * Author : WCH - * Version : V1.0.0 - * Date : 2021/06/06 - * Description : RISC-V Core Peripheral Access Layer Header File for CH32V20x -********************************************************************************* -* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. -* Attention: This software (modified or not) and binary are used for -* microcontroller manufactured by Nanjing Qinheng Microelectronics. -*******************************************************************************/ -#ifndef __CORE_RISCV_H__ -#define __CORE_RISCV_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* IO definitions */ -#ifdef __cplusplus - #define __I volatile /* defines 'read only' permissions */ -#else - #define __I volatile const /* defines 'read only' permissions */ -#endif -#define __O volatile /* defines 'write only' permissions */ -#define __IO volatile /* defines 'read / write' permissions */ - -/* Standard Peripheral Library old types (maintained for legacy purpose) */ -typedef __I uint64_t vuc64; /* Read Only */ -typedef __I uint32_t vuc32; /* Read Only */ -typedef __I uint16_t vuc16; /* Read Only */ -typedef __I uint8_t vuc8; /* Read Only */ - -typedef const uint64_t uc64; /* Read Only */ -typedef const uint32_t uc32; /* Read Only */ -typedef const uint16_t uc16; /* Read Only */ -typedef const uint8_t uc8; /* Read Only */ - -typedef __I int64_t vsc64; /* Read Only */ -typedef __I int32_t vsc32; /* Read Only */ -typedef __I int16_t vsc16; /* Read Only */ -typedef __I int8_t vsc8; /* Read Only */ - -typedef const int64_t sc64; /* Read Only */ -typedef const int32_t sc32; /* Read Only */ -typedef const int16_t sc16; /* Read Only */ -typedef const int8_t sc8; /* Read Only */ - -typedef __IO uint64_t vu64; -typedef __IO uint32_t vu32; -typedef __IO uint16_t vu16; -typedef __IO uint8_t vu8; - -typedef uint64_t u64; -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; - -typedef __IO int64_t vs64; -typedef __IO int32_t vs32; -typedef __IO int16_t vs16; -typedef __IO int8_t vs8; - -typedef int64_t s64; -typedef int32_t s32; -typedef int16_t s16; -typedef int8_t s8; - -typedef enum {NoREADY = 0, READY = !NoREADY} ErrorStatus; - -typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; - -typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; - -#define RV_STATIC_INLINE static inline - -/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */ -typedef struct{ - __I uint32_t ISR[8]; - __I uint32_t IPR[8]; - __IO uint32_t ITHRESDR; - __IO uint32_t RESERVED; - __IO uint32_t CFGR; - __I uint32_t GISR; - __IO uint8_t VTFIDR[4]; - uint8_t RESERVED0[12]; - __IO uint32_t VTFADDR[4]; - uint8_t RESERVED1[0x90]; - __O uint32_t IENR[8]; - uint8_t RESERVED2[0x60]; - __O uint32_t IRER[8]; - uint8_t RESERVED3[0x60]; - __O uint32_t IPSR[8]; - uint8_t RESERVED4[0x60]; - __O uint32_t IPRR[8]; - uint8_t RESERVED5[0x60]; - __IO uint32_t IACTR[8]; - uint8_t RESERVED6[0xE0]; - __IO uint8_t IPRIOR[256]; - uint8_t RESERVED7[0x810]; - __IO uint32_t SCTLR; -}PFIC_Type; - -/* memory mapped structure for SysTick */ -typedef struct -{ - __IO uint32_t CTLR; - __IO uint32_t SR; - __IO uint64_t CNT; - __IO uint64_t CMP; -}SysTick_Type; - -#define PFIC ((PFIC_Type *) 0xE000E000 ) -#define NVIC PFIC -#define NVIC_KEY1 ((uint32_t)0xFA050000) -#define NVIC_KEY2 ((uint32_t)0xBCAF0000) -#define NVIC_KEY3 ((uint32_t)0xBEEF0000) - -#define SysTick ((SysTick_Type *) 0xE000F000) - -/********************************************************************* - * @fn __enable_irq - * - * @brief Enable Global Interrupt - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __enable_irq(void) -{ - __asm volatile ("csrw 0x800, %0" : : "r" (0x6088) ); -} - -/********************************************************************* - * @fn __disable_irq - * - * @brief Disable Global Interrupt - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __disable_irq(void) -{ - __asm volatile ("csrw 0x800, %0" : : "r" (0x6000) ); -} - -/********************************************************************* - * @fn __NOP - * - * @brief nop - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __NOP(void) -{ - __asm volatile ("nop"); -} - -/********************************************************************* - * @fn NVIC_EnableIRQ - * - * @brief Disable Interrupt - * - * @param IRQn - Interrupt Numbers - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_DisableIRQ - * - * @brief Disable Interrupt - * - * @param IRQn - Interrupt Numbers - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_GetStatusIRQ - * - * @brief Get Interrupt Enable State - * - * @param IRQn - Interrupt Numbers - * - * @return 1 - Interrupt Pending Enable - * 0 - Interrupt Pending Disable - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetStatusIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_GetPendingIRQ - * - * @brief Get Interrupt Pending State - * - * @param IRQn - Interrupt Numbers - * - * @return 1 - Interrupt Pending Enable - * 0 - Interrupt Pending Disable - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_SetPendingIRQ - * - * @brief Set Interrupt Pending - * - * @param IRQn - Interrupt Numbers - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_ClearPendingIRQ - * - * @brief Clear Interrupt Pending - * - * @param IRQn - Interrupt Numbers - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_GetActive - * - * @brief Get Interrupt Active State - * - * @param IRQn - Interrupt Numbers - * - * @return 1 - Interrupt Active - * 0 - Interrupt No Active - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)((NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_SetPriority - * - * @brief Set Interrupt Priority - * - * @param IRQn - Interrupt Numbers - * priority - bit7 - Pre-emption Priority - * bit[6:5] - Subpriority - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority) -{ - NVIC->IPRIOR[(uint32_t)(IRQn)] = priority; -} - -/********************************************************************* - * @fn __WFI - * - * @brief Wait for Interrupt - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void) -{ - NVIC->SCTLR &= ~(1<<3); // wfi - asm volatile ("wfi"); -} - -/********************************************************************* - * @fn _SEV - * - * @brief Set Event - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _SEV(void) -{ - uint32_t t; - - t = NVIC->SCTLR; - NVIC->SCTLR |= (1<<3)|(1<<5); - NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5)); -} - -/********************************************************************* - * @fn _WFE - * - * @brief Wait for Events - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _WFE(void) -{ - NVIC->SCTLR |= (1<<3); - asm volatile ("wfi"); -} - -/********************************************************************* - * @fn __WFE - * - * @brief Wait for Events - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void) -{ - _SEV(); - _WFE(); - _WFE(); -} - -/********************************************************************* - * @fn SetVTFIRQ - * - * @brief Set VTF Interrupt - * - * @param addr - VTF interrupt service function base address. - * IRQn - Interrupt Numbers - * num - VTF Interrupt Numbers - * NewState - DISABLE or ENABLE - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){ - if(num > 3) return ; - - if (NewState != DISABLE) - { - NVIC->VTFIDR[num] = IRQn; - NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1); - } - else{ - NVIC->VTFIDR[num] = IRQn; - NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1)); - } -} - -/********************************************************************* - * @fn NVIC_SystemReset - * - * @brief Initiate a system reset request - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SystemReset(void) -{ - NVIC->CFGR = NVIC_KEY3|(1<<7); -} - -/********************************************************************* - * @fn __AMOADD_W - * - * @brief Atomic Add with 32bit value - * Atomically ADD 32bit value with value in memory using amoadd.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be ADDed - * - * @return return memory value + add value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOADD_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoadd.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOAND_W - * - * @brief Atomic And with 32bit value - * Atomically AND 32bit value with value in memory using amoand.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be ANDed - * - * @return return memory value & and value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOAND_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoand.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOMAX_W - * - * @brief Atomic signed MAX with 32bit value - * Atomically signed max compare 32bit value with value in memory using amomax.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be compared - * - * @return the bigger value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMAX_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amomax.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOMAXU_W - * - * @brief Atomic unsigned MAX with 32bit value - * Atomically unsigned max compare 32bit value with value in memory using amomaxu.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be compared - * - * @return return the bigger value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMAXU_W(volatile uint32_t *addr, uint32_t value) -{ - uint32_t result; - - __asm volatile ("amomaxu.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOMIN_W - * - * @brief Atomic signed MIN with 32bit value - * Atomically signed min compare 32bit value with value in memory using amomin.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be compared - * - * @return the smaller value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMIN_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amomin.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOMINU_W - * - * @brief Atomic unsigned MIN with 32bit value - * Atomically unsigned min compare 32bit value with value in memory using amominu.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be compared - * - * @return the smaller value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMINU_W(volatile uint32_t *addr, uint32_t value) -{ - uint32_t result; - - __asm volatile ("amominu.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOOR_W - * - * @brief Atomic OR with 32bit value - * Atomically OR 32bit value with value in memory using amoor.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be ORed - * - * @return return memory value | and value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOOR_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoor.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOSWAP_W - * - * @brief Atomically swap new 32bit value into memory using amoswap.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * newval - New value to be stored into the address - * - * @return return the original value in memory - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOSWAP_W(volatile uint32_t *addr, uint32_t newval) -{ - uint32_t result; - - __asm volatile ("amoswap.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(newval) : "memory"); - return result; -} - -/********************************************************************* - * @fn __AMOXOR_W - * - * @brief Atomic XOR with 32bit value - * Atomically XOR 32bit value with value in memory using amoxor.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be XORed - * - * @return return memory value ^ and value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOXOR_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoxor.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/* Core_Exported_Functions */ -extern uint32_t __get_MSTATUS(void); -extern void __set_MSTATUS(uint32_t value); -extern uint32_t __get_MISA(void); -extern void __set_MISA(uint32_t value); -extern uint32_t __get_MTVEC(void); -extern void __set_MTVEC(uint32_t value); -extern uint32_t __get_MSCRATCH(void); -extern void __set_MSCRATCH(uint32_t value); -extern uint32_t __get_MEPC(void); -extern void __set_MEPC(uint32_t value); -extern uint32_t __get_MCAUSE(void); -extern void __set_MCAUSE(uint32_t value); -extern uint32_t __get_MTVAL(void); -extern void __set_MTVAL(uint32_t value); -extern uint32_t __get_MVENDORID(void); -extern uint32_t __get_MARCHID(void); -extern uint32_t __get_MIMPID(void); -extern uint32_t __get_MHARTID(void); -extern uint32_t __get_SP(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/hw/bsp/ch32v20x/family.c b/hw/bsp/ch32v20x/family.c index c32cfd46e..8575f5699 100644 --- a/hw/bsp/ch32v20x/family.c +++ b/hw/bsp/ch32v20x/family.c @@ -1,6 +1,18 @@ #include + +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #include "ch32v20x.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "bsp/board_api.h" #include "board.h" diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake index 1d574fdf8..28fd13697 100644 --- a/hw/bsp/ch32v20x/family.cmake +++ b/hw/bsp/ch32v20x/family.cmake @@ -49,6 +49,7 @@ function(add_board_target BOARD_TARGET) ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_SRC_DIR}/Core ${SDK_SRC_DIR}/Peripheral/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index 49d4d2feb..daf3148f8 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -24,6 +24,9 @@ CFLAGS += \ -DCH32V20x_${MCU_VARIANT} \ -DCFG_TUSB_MCU=OPT_MCU_CH32V20X +# https://github.com/openwch/ch32v20x/pull/12 +CFLAGS += -Wno-error=strict-prototypes + ifeq ($(PORT),0) $(info "Using FSDEV driver") CFLAGS += -DCFG_TUD_WCH_USBIP_FSDEV=1 @@ -51,6 +54,7 @@ SRC_S += $(SDK_SRC_DIR)/Startup/startup_ch32v20x_${MCU_VARIANT}.S INC += \ $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(SDK_SRC_DIR)/Core \ $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc \ FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V diff --git a/hw/bsp/ch32v307/core_riscv.h b/hw/bsp/ch32v307/core_riscv.h deleted file mode 100644 index a7ce10a00..000000000 --- a/hw/bsp/ch32v307/core_riscv.h +++ /dev/null @@ -1,379 +0,0 @@ -/********************************** (C) COPYRIGHT ******************************* -* File Name : core_riscv.h -* Author : WCH -* Version : V1.0.0 -* Date : 2021/06/06 -* Description : RISC-V Core Peripheral Access Layer Header File for CH32V30x -* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. -* SPDX-License-Identifier: Apache-2.0 -*******************************************************************************/ -#ifndef __CORE_RISCV_H__ -#define __CORE_RISCV_H__ - -/* IO definitions */ -#ifdef __cplusplus - #define __I volatile /* defines 'read only' permissions */ -#else - #define __I volatile const /* defines 'read only' permissions */ -#endif -#define __O volatile /* defines 'write only' permissions */ -#define __IO volatile /* defines 'read / write' permissions */ - -/* Standard Peripheral Library old types (maintained for legacy purpose) */ -typedef __I uint64_t vuc64; /* Read Only */ -typedef __I uint32_t vuc32; /* Read Only */ -typedef __I uint16_t vuc16; /* Read Only */ -typedef __I uint8_t vuc8; /* Read Only */ - -typedef const uint64_t uc64; /* Read Only */ -typedef const uint32_t uc32; /* Read Only */ -typedef const uint16_t uc16; /* Read Only */ -typedef const uint8_t uc8; /* Read Only */ - -typedef __I int64_t vsc64; /* Read Only */ -typedef __I int32_t vsc32; /* Read Only */ -typedef __I int16_t vsc16; /* Read Only */ -typedef __I int8_t vsc8; /* Read Only */ - -typedef const int64_t sc64; /* Read Only */ -typedef const int32_t sc32; /* Read Only */ -typedef const int16_t sc16; /* Read Only */ -typedef const int8_t sc8; /* Read Only */ - -typedef __IO uint64_t vu64; -typedef __IO uint32_t vu32; -typedef __IO uint16_t vu16; -typedef __IO uint8_t vu8; - -typedef uint64_t u64; -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; - -typedef __IO int64_t vs64; -typedef __IO int32_t vs32; -typedef __IO int16_t vs16; -typedef __IO int8_t vs8; - -typedef int64_t s64; -typedef int32_t s32; -typedef int16_t s16; -typedef int8_t s8; - -typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; - -typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; - -typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; - -#define RV_STATIC_INLINE static inline - -/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */ -typedef struct{ - __I uint32_t ISR[8]; - __I uint32_t IPR[8]; - __IO uint32_t ITHRESDR; - __IO uint32_t RESERVED; - __IO uint32_t CFGR; - __I uint32_t GISR; - uint8_t VTFIDR[4]; - uint8_t RESERVED0[12]; - __IO uint32_t VTFADDR[4]; - uint8_t RESERVED1[0x90]; - __O uint32_t IENR[8]; - uint8_t RESERVED2[0x60]; - __O uint32_t IRER[8]; - uint8_t RESERVED3[0x60]; - __O uint32_t IPSR[8]; - uint8_t RESERVED4[0x60]; - __O uint32_t IPRR[8]; - uint8_t RESERVED5[0x60]; - __IO uint32_t IACTR[8]; - uint8_t RESERVED6[0xE0]; - __IO uint8_t IPRIOR[256]; - uint8_t RESERVED7[0x810]; - __IO uint32_t SCTLR; -}PFIC_Type; - -/* memory mapped structure for SysTick */ -typedef struct -{ - __IO u32 CTLR; - __IO u32 SR; - __IO u64 CNT; - __IO u64 CMP; -}SysTick_Type; - - -#define PFIC ((PFIC_Type *) 0xE000E000 ) -#define NVIC PFIC -#define NVIC_KEY1 ((uint32_t)0xFA050000) -#define NVIC_KEY2 ((uint32_t)0xBCAF0000) -#define NVIC_KEY3 ((uint32_t)0xBEEF0000) - -#define SysTick ((SysTick_Type *) 0xE000F000) - - -/********************************************************************* - * @fn __enable_irq - * - * @brief Enable Global Interrupt - * - * @return none - */ -RV_STATIC_INLINE void __enable_irq(void) -{ - __asm volatile ("csrw 0x800, %0" : : "r" (0x6088) ); -} - -/********************************************************************* - * @fn __disable_irq - * - * @brief Disable Global Interrupt - * - * @return none - */ -RV_STATIC_INLINE void __disable_irq(void) -{ - __asm volatile ("csrw 0x800, %0" : : "r" (0x6000) ); -} - -/********************************************************************* - * @fn __NOP - * - * @brief nop - * - * @return none - */ -RV_STATIC_INLINE void __NOP(void) -{ - __asm volatile ("nop"); -} - -/********************************************************************* - * @fn NVIC_EnableIRQ - * - * @brief Enable Interrupt - * - * @param IRQn: Interrupt Numbers - * - * @return none - */ -RV_STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_DisableIRQ - * - * @brief Disable Interrupt - * - * @param IRQn: Interrupt Numbers - * - * @return none - */ -RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_GetStatusIRQ - * - * @brief Get Interrupt Enable State - * - * @param IRQn: Interrupt Numbers - * - * @return 1 - Interrupt Enable - * 0 - Interrupt Disable - */ -RV_STATIC_INLINE uint32_t NVIC_GetStatusIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_GetPendingIRQ - * - * @brief Get Interrupt Pending State - * - * @param IRQn: Interrupt Numbers - * - * @return 1 - Interrupt Pending Enable - * 0 - Interrupt Pending Disable - */ -RV_STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_SetPendingIRQ - * - * @brief Set Interrupt Pending - * - * @param IRQn: Interrupt Numbers - * - * @return None - */ -RV_STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_ClearPendingIRQ - * - * @brief Clear Interrupt Pending - * - * @param IRQn: Interrupt Numbers - * - * @return None - */ -RV_STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_GetActive - * - * @brief Get Interrupt Active State - * - * @param IRQn: Interrupt Numbers - * - * @return 1 - Interrupt Active - * 0 - Interrupt No Active - */ -RV_STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)((NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_SetPriority - * - * @brief Set Interrupt Priority - * - * @param IRQn - Interrupt Numbers - * priority - - * bit7 - pre-emption priority - * bit6~bit4 - subpriority - * @return None - */ -RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority) -{ - NVIC->IPRIOR[(uint32_t)(IRQn)] = priority; -} - -/********************************************************************* - * @fn __WFI - * - * @brief Wait for Interrupt - * - * @return None - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void) -{ - NVIC->SCTLR &= ~(1<<3); // wfi - asm volatile ("wfi"); -} - -/********************************************************************* - * @fn __WFE - * - * @brief Wait for Events - * - * @return None - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void) -{ - uint32_t t; - - t = NVIC->SCTLR; - NVIC->SCTLR |= (1<<3)|(1<<5); // (wfi->wfe)+(__sev) - NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5)); - asm volatile ("wfi"); - asm volatile ("wfi"); -} - -/********************************************************************* - * @fn SetVTFIRQ - * - * @brief Set VTF Interrupt - * - * @param add - VTF interrupt service function base address. - * IRQn -Interrupt Numbers - * num - VTF Interrupt Numbers - * NewState - DISABLE or ENABLE - * @return None - */ -RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){ - if(num > 3) return ; - - if (NewState != DISABLE) - { - NVIC->VTFIDR[num] = IRQn; - NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1); - } - else{ - NVIC->VTFIDR[num] = IRQn; - NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1)); - } -} - -/********************************************************************* - * @fn NVIC_SystemReset - * - * @brief Initiate a system reset request - * - * @return None - */ -RV_STATIC_INLINE void NVIC_SystemReset(void) -{ - NVIC->CFGR = NVIC_KEY3|(1<<7); -} - - -/* Core_Exported_Functions */ -extern uint32_t __get_FFLAGS(void); -extern void __set_FFLAGS(uint32_t value); -extern uint32_t __get_FRM(void); -extern void __set_FRM(uint32_t value); -extern uint32_t __get_FCSR(void); -extern void __set_FCSR(uint32_t value); -extern uint32_t __get_MSTATUS(void); -extern void __set_MSTATUS(uint32_t value); -extern uint32_t __get_MISA(void); -extern void __set_MISA(uint32_t value); -extern uint32_t __get_MIE(void); -extern void __set_MIE(uint32_t value); -extern uint32_t __get_MTVEC(void); -extern void __set_MTVEC(uint32_t value); -extern uint32_t __get_MSCRATCH(void); -extern void __set_MSCRATCH(uint32_t value); -extern uint32_t __get_MEPC(void); -extern void __set_MEPC(uint32_t value); -extern uint32_t __get_MCAUSE(void); -extern void __set_MCAUSE(uint32_t value); -extern uint32_t __get_MTVAL(void); -extern void __set_MTVAL(uint32_t value); -extern uint32_t __get_MIP(void); -extern void __set_MIP(uint32_t value); -extern uint32_t __get_MCYCLE(void); -extern void __set_MCYCLE(uint32_t value); -extern uint32_t __get_MCYCLEH(void); -extern void __set_MCYCLEH(uint32_t value); -extern uint32_t __get_MINSTRET(void); -extern void __set_MINSTRET(uint32_t value); -extern uint32_t __get_MINSTRETH(void); -extern void __set_MINSTRETH(uint32_t value); -extern uint32_t __get_MVENDORID(void); -extern uint32_t __get_MARCHID(void); -extern uint32_t __get_MIMPID(void); -extern uint32_t __get_MHARTID(void); -extern uint32_t __get_SP(void); - - -#endif diff --git a/hw/bsp/ch32v307/debug_uart.c b/hw/bsp/ch32v307/debug_uart.c index fbabeeadc..2fd3a9d64 100644 --- a/hw/bsp/ch32v307/debug_uart.c +++ b/hw/bsp/ch32v307/debug_uart.c @@ -25,8 +25,17 @@ */ #include "debug_uart.h" + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #include +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif #define UART_RINGBUFFER_SIZE_TX 128 #define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1) diff --git a/hw/bsp/ch32v307/family.c b/hw/bsp/ch32v307/family.c index 0846b10a9..adf2dbea5 100644 --- a/hw/bsp/ch32v307/family.c +++ b/hw/bsp/ch32v307/family.c @@ -25,9 +25,22 @@ */ #include "stdio.h" + +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #include "debug_uart.h" #include "ch32v30x.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "bsp/board_api.h" #include "board.h" diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake index af26bfc31..d603af62d 100644 --- a/hw/bsp/ch32v307/family.cmake +++ b/hw/bsp/ch32v307/family.cmake @@ -49,6 +49,7 @@ function(add_board_target BOARD_TARGET) ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_SRC_DIR}/Core ${SDK_SRC_DIR}/Peripheral/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index 30a070a9b..bf2732106 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -25,6 +25,9 @@ CFLAGS += \ -fsigned-char \ -DCFG_TUSB_MCU=OPT_MCU_CH32V307 \ +# https://github.com/openwch/ch32v307/pull/90 +CFLAGS += -Wno-error=strict-prototypes + ifeq ($(SPEED),high) $(info "Using USBHS driver for HighSpeed mode") CFLAGS += -DCFG_TUD_WCH_USBIP_USBHS=1 @@ -51,6 +54,7 @@ SRC_S += \ INC += \ $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(SDK_SRC_DIR)/Core \ $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc # For freeRTOS port source diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h index 85fe3266c..dbf2a0289 100644 --- a/src/portable/st/stm32_fsdev/fsdev_ch32.h +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -36,13 +36,23 @@ #include "common/tusb_compiler.h" +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #if CFG_TUSB_MCU == OPT_MCU_CH32V20X #include - #elif CFG_TUSB_MCU == OPT_MCU_CH32F20X #include #endif +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #define FSDEV_PMA_SIZE (512u) // volatile 32-bit aligned diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h index 0a50a6169..ef6ebf2dc 100644 --- a/src/portable/wch/ch32_usbfs_reg.h +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -28,6 +28,13 @@ #ifndef USB_CH32_USBFS_REG_H #define USB_CH32_USBFS_REG_H +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #if CFG_TUSB_MCU == OPT_MCU_CH32V307 #include #define USBHD_IRQn OTG_FS_IRQn @@ -39,6 +46,10 @@ #include #endif +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + // CTRL #define USBFS_CTRL_DMA_EN (1 << 0) #define USBFS_CTRL_CLR_ALL (1 << 1) diff --git a/src/portable/wch/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h index 130e4f223..87300b497 100644 --- a/src/portable/wch/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -28,12 +28,24 @@ #ifndef USB_CH32_USBHS_REG_H #define USB_CH32_USBHS_REG_H +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #if CFG_TUSB_MCU == OPT_MCU_CH32V307 #include #elif CFG_TUSB_MCU == OPT_MCU_CH32F20X #include #endif +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + + /******************* GLOBAL ******************/ // USB CONTROL -- cgit v1.3.1 From 969b06d77c8a37510c9bed8dde377ff7bf462a30 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 12:51:50 +0700 Subject: minor update --- src/class/hid/hid.h | 4 ++-- src/class/net/ncm_device.c | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index 2fe922136..c2b5a8a48 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -762,7 +762,7 @@ enum { HID_USAGE_PAGE_ALPHA_DISPLAY = 0x14, HID_USAGE_PAGE_MEDICAL = 0x40, HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION = 0x59, - HID_USAGE_PAGE_MONITOR = 0x80, //0x80 - 0x83 + HID_USAGE_PAGE_MONITOR = 0x80, // 0x80 - 0x83 HID_USAGE_PAGE_POWER = 0x84, // 0x084 - 0x87 HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c, HID_USAGE_PAGE_SCALE = 0x8d, @@ -770,7 +770,7 @@ enum { HID_USAGE_PAGE_CAMERA = 0x90, HID_USAGE_PAGE_ARCADE = 0x91, HID_USAGE_PAGE_FIDO = 0xF1D0, // FIDO alliance HID usage page - HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF + HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF }; /// HID Usage Table - Table 6: Generic Desktop Page diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 64aba011a..44a6a0de9 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -1,6 +1,8 @@ /* * The MIT License (MIT) * + * Copyright (c) 2020 Jacob Berg Potter + * Copyright (c) 2020 Peter Lawrence * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2024 Hardy Griech * -- cgit v1.3.1 From 33f5547ed435f33259afc2a8e906eb7a258fbdd6 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 16:06:37 +0700 Subject: add ch32v103 bsp support, compile but does not run, probably due to compile/linker issue --- .../ch32v10x/boards/ch32v103r_r1_1v0/board.cmake | 8 + hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h | 20 + hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk | 7 + hw/bsp/ch32v10x/ch32v10x_conf.h | 37 ++ hw/bsp/ch32v10x/ch32v10x_it.h | 15 + hw/bsp/ch32v10x/family.c | 147 +++++ hw/bsp/ch32v10x/family.cmake | 117 ++++ hw/bsp/ch32v10x/family.mk | 53 ++ hw/bsp/ch32v10x/linker/ch32v10x.ld | 165 ++++++ hw/bsp/ch32v10x/system_ch32v10x.c | 600 +++++++++++++++++++++ hw/bsp/ch32v10x/system_ch32v10x.h | 29 + hw/bsp/ch32v10x/wch-riscv.cfg | 17 + hw/bsp/ch32v20x/family.mk | 10 +- hw/bsp/family_support.cmake | 2 +- src/common/tusb_mcu.h | 9 + src/portable/wch/ch32_usbfs_reg.h | 67 ++- src/tusb_option.h | 6 +- tools/get_deps.py | 3 + 18 files changed, 1296 insertions(+), 16 deletions(-) create mode 100644 hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.cmake create mode 100644 hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h create mode 100644 hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk create mode 100644 hw/bsp/ch32v10x/ch32v10x_conf.h create mode 100644 hw/bsp/ch32v10x/ch32v10x_it.h create mode 100644 hw/bsp/ch32v10x/family.c create mode 100644 hw/bsp/ch32v10x/family.cmake create mode 100644 hw/bsp/ch32v10x/family.mk create mode 100644 hw/bsp/ch32v10x/linker/ch32v10x.ld create mode 100644 hw/bsp/ch32v10x/system_ch32v10x.c create mode 100644 hw/bsp/ch32v10x/system_ch32v10x.h create mode 100644 hw/bsp/ch32v10x/wch-riscv.cfg diff --git a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.cmake b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.cmake new file mode 100644 index 000000000..f6e47ba30 --- /dev/null +++ b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.cmake @@ -0,0 +1,8 @@ +set(LD_FLASH_SIZE 64K) +set(LD_RAM_SIZE 20K) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + CFG_EXAMPLE_MSC_DUAL_READONLY + ) +endfunction() diff --git a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h new file mode 100644 index 000000000..3b1187c3a --- /dev/null +++ b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h @@ -0,0 +1,20 @@ +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define LED_PORT GPIOA +#define LED_PIN GPIO_Pin_10 +#define LED_STATE_ON 0 + +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_Pin_1 +#define BUTTON_STATE_ACTIVE 0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk new file mode 100644 index 000000000..7d7462312 --- /dev/null +++ b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk @@ -0,0 +1,7 @@ +MCU_VARIANT = D6 + +CFLAGS += -DCFG_EXAMPLE_MSC_DUAL_READONLY + +LDFLAGS += \ + -Wl,--defsym=__flash_size=64K \ + -Wl,--defsym=__ram_size=20K \ diff --git a/hw/bsp/ch32v10x/ch32v10x_conf.h b/hw/bsp/ch32v10x/ch32v10x_conf.h new file mode 100644 index 000000000..939c0fbde --- /dev/null +++ b/hw/bsp/ch32v10x/ch32v10x_conf.h @@ -0,0 +1,37 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : ch32v10x_conf.h + * Author : WCH + * Version : V1.0.0 + * Date : 2020/04/30 + * Description : Library configuration file. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __CH32V10x_CONF_H +#define __CH32V10x_CONF_H + +#include "ch32v10x_adc.h" +#include "ch32v10x_bkp.h" +#include "ch32v10x_crc.h" +#include "ch32v10x_dbgmcu.h" +#include "ch32v10x_dma.h" +#include "ch32v10x_exti.h" +#include "ch32v10x_flash.h" +#include "ch32v10x_gpio.h" +#include "ch32v10x_i2c.h" +#include "ch32v10x_iwdg.h" +#include "ch32v10x_pwr.h" +#include "ch32v10x_rcc.h" +#include "ch32v10x_rtc.h" +#include "ch32v10x_spi.h" +#include "ch32v10x_tim.h" +#include "ch32v10x_usart.h" +#include "ch32v10x_wwdg.h" +#include "ch32v10x_usb.h" +#include "ch32v10x_usb_host.h" +#include "ch32v10x_it.h" +#include "ch32v10x_misc.h" + +#endif /* __CH32V10x_CONF_H */ diff --git a/hw/bsp/ch32v10x/ch32v10x_it.h b/hw/bsp/ch32v10x/ch32v10x_it.h new file mode 100644 index 000000000..13afc2412 --- /dev/null +++ b/hw/bsp/ch32v10x/ch32v10x_it.h @@ -0,0 +1,15 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : ch32v10x_it.h + * Author : WCH + * Version : V1.0.0 + * Date : 2022/08/20 + * Description : This file contains the headers of the interrupt handlers. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __CH32V10x_IT_H +#define __CH32V10x_IT_H + +#endif /* __CH32V10x_IT_H */ diff --git a/hw/bsp/ch32v10x/family.c b/hw/bsp/ch32v10x/family.c new file mode 100644 index 000000000..6de17521e --- /dev/null +++ b/hw/bsp/ch32v10x/family.c @@ -0,0 +1,147 @@ +#include + +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + +#include "ch32v10x.h" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#include "bsp/board_api.h" +#include "board.h" + +__attribute__((interrupt)) __attribute__((used)) +void USBHD_IRQHandler(void) { + #if CFG_TUD_WCH_USBIP_USBFS + tud_int_handler(0); + #endif +} + +__attribute__((interrupt)) __attribute__((used)) +void USBHDWakeUp_IRQHandler(void) { + #if CFG_TUD_WCH_USBIP_USBFS + tud_int_handler(0); + #endif +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +__attribute__((interrupt)) __attribute__((used)) +void SysTick_Handler(void) { + SysTick->CNTL0 = SysTick->CNTL1 = SysTick->CNTL2 = SysTick->CNTL3 = 0; + SysTick->CNTH0 = SysTick->CNTH1 = SysTick->CNTH2 = SysTick->CNTH3 = 0; + system_ticks++; +} + +uint32_t SysTick_Config(uint32_t ticks) { + NVIC_EnableIRQ(SysTicK_IRQn); + SysTick->CTLR = 0; + SysTick->CNTL0 = SysTick->CNTL1 = SysTick->CNTL2 = SysTick->CNTL3 = 0; + SysTick->CNTH0 = SysTick->CNTH1 = SysTick->CNTH2 = SysTick->CNTH3 = 0; + + SysTick->CMPLR0 = (u8)(ticks & 0xFF); + SysTick->CMPLR1 = (u8)(ticks >> 8); + SysTick->CMPLR2 = (u8)(ticks >> 16); + SysTick->CMPLR3 = (u8)(ticks >> 24); + + SysTick->CMPHR0 = SysTick->CMPHR1 = SysTick->CMPHR2 = SysTick->CMPHR3 = 0; + SysTick->CTLR = 1; + return 0; +} + +uint32_t board_millis(void) { + return system_ticks; +} +#endif + +void board_init(void) { + __disable_irq(); + +#if CFG_TUSB_OS == OPT_OS_NONE + SysTick_Config(SystemCoreClock / 1000); +#endif + + uint8_t usb_div; + switch (SystemCoreClock) { + case 48000000: usb_div = RCC_USBCLKSource_PLLCLK_Div1; break; + case 72000000: usb_div = RCC_USBCLKSource_PLLCLK_1Div5; break; + default: TU_ASSERT(0,); break; + } + RCC_USBCLKConfig(usb_div); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); + + #ifdef LED_PIN + GPIO_InitTypeDef led_init = { + .GPIO_Pin = LED_PIN, + .GPIO_Mode = GPIO_Mode_Out_OD, + .GPIO_Speed = GPIO_Speed_50MHz, + }; + GPIO_Init(LED_PORT, &led_init); + #endif + + #ifdef BUTTON_PIN + GPIO_InitTypeDef button_init = { + .GPIO_Pin = BUTTON_PIN, + .GPIO_Mode = GPIO_Mode_IPU, + .GPIO_Speed = GPIO_Speed_50MHz, + }; + GPIO_Init(BUTTON_PORT, &button_init); + #endif + + // UART TX is PA9 + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); + GPIO_InitTypeDef usart_init = { + .GPIO_Pin = GPIO_Pin_9, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_AF_PP, + }; + GPIO_Init(GPIOA, &usart_init); + + USART_InitTypeDef usart = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_StopBits = USART_StopBits_1, + .USART_Parity = USART_Parity_No, + .USART_Mode = USART_Mode_Tx, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + }; + USART_Init(USART1, &usart); + USART_Cmd(USART1, ENABLE); + + __enable_irq(); + + board_led_write(true); +} + +void board_led_write(bool state) { + GPIO_WriteBit(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) { + return BUTTON_STATE_ACTIVE == GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t *buf, int len) { + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const *buf, int len) { + const char *bufc = (const char *) buf; + for (int i = 0; i < len; i++) { + while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); + USART_SendData(USART1, *bufc++); + } + + return len; +} diff --git a/hw/bsp/ch32v10x/family.cmake b/hw/bsp/ch32v10x/family.cmake new file mode 100644 index 000000000..b0d8241d3 --- /dev/null +++ b/hw/bsp/ch32v10x/family.cmake @@ -0,0 +1,117 @@ +include_guard() + +#set(UF2_FAMILY_ID 0x699b62ec) +set(CH32_FAMILY ch32v10x) +set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v103) +set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR rv32imac-ilp32 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS CH32V103 CACHE INTERNAL "") +set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${CH32_FAMILY}.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_${CH32_FAMILY}.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_SRC_DIR}/Core/core_riscv.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_SRC_DIR}/Core + ${SDK_SRC_DIR}/Peripheral/inc + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC + -mcmodel=medany + ) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -Wl,--defsym=__flash_size=${LD_FLASH_SIZE} + -Wl,--defsym=__ram_size=${LD_RAM_SIZE} + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for MSP432E4") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_CH32V103 ${RTOS}) + + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/wch/dcd_ch32_usbfs.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_openocd_wch(${TARGET}) + + #family_add_uf2(${TARGET} ${UF2_FAMILY_ID}) + #family_flash_uf2(${TARGET} ${UF2_FAMILY_ID}) +endfunction() diff --git a/hw/bsp/ch32v10x/family.mk b/hw/bsp/ch32v10x/family.mk new file mode 100644 index 000000000..d96d5012e --- /dev/null +++ b/hw/bsp/ch32v10x/family.mk @@ -0,0 +1,53 @@ +# https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable +#CROSS_COMPILE ?= riscv32-unknown-elf- + +# Toolchain from https://nucleisys.com/download.php +#CROSS_COMPILE ?= riscv-nuclei-elf- + +# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +CROSS_COMPILE ?= riscv-none-elf- + +CH32_FAMILY = ch32v10x +SDK_DIR = hw/mcu/wch/ch32v103 +SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC + +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= rv32imac-ilp32 + +# Port0 use FSDev, Port1 use USBFS +PORT ?= 0 + +CFLAGS += \ + -mcmodel=medany \ + -ffat-lto-objects \ + -flto \ + -DCFG_TUSB_MCU=OPT_MCU_CH32V103 + +# https://github.com/openwch/ch32v20x/pull/12 +CFLAGS += -Wno-error=strict-prototypes + +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ + +LD_FILE = $(FAMILY_PATH)/linker/${CH32_FAMILY}.ld + +SRC_C += \ + src/portable/wch/dcd_ch32_usbfs.c \ + $(SDK_SRC_DIR)/Core/core_riscv.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_misc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_rcc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_usart.c \ + +SRC_S += $(SDK_SRC_DIR)/Startup/startup_${CH32_FAMILY}.S + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(SDK_SRC_DIR)/Core \ + $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc \ + +FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V + +OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg +flash: flash-openocd-wch diff --git a/hw/bsp/ch32v10x/linker/ch32v10x.ld b/hw/bsp/ch32v10x/linker/ch32v10x.ld new file mode 100644 index 000000000..cd5c8dc17 --- /dev/null +++ b/hw/bsp/ch32v10x/linker/ch32v10x.ld @@ -0,0 +1,165 @@ +/* Define default values if not already defined */ +__FLASH_SIZE = DEFINED(__flash_size) ? __flash_size : 64K; +__RAM_SIZE = DEFINED(__ram_size) ? __ram_size : 20K; + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __FLASH_SIZE + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __RAM_SIZE +} + +ENTRY( _start ) + +__stack_size = 2048; + +PROVIDE( _stack_size = __stack_size ); + +SECTIONS +{ + .init : + { + _sinit = .; + . = ALIGN(4); + KEEP(*(SORT_NONE(.init))) + . = ALIGN(4); + _einit = .; + } >FLASH AT>FLASH + + .vector : + { + *(.vector); + . = ALIGN(64); + } >FLASH AT>FLASH + + .text : + { + . = ALIGN(4); + *(.text) + *(.text.*) + *(.rodata) + *(.rodata*) + *(.gnu.linkonce.t.*) + . = ALIGN(4); + } >FLASH AT>FLASH + + .fini : + { + KEEP(*(SORT_NONE(.fini))) + . = ALIGN(4); + } >FLASH AT>FLASH + + PROVIDE( _etext = . ); + PROVIDE( _eitcm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH AT>FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH AT>FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH AT>FLASH + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >FLASH AT>FLASH + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >FLASH AT>FLASH + + .dalign : + { + . = ALIGN(4); + PROVIDE(_data_vma = .); + } >RAM AT>FLASH + + .dlalign : + { + . = ALIGN(4); + PROVIDE(_data_lma = .); + } >FLASH AT>FLASH + + .data : + { + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.sdata2.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + . = ALIGN(4); + PROVIDE( _edata = .); + } >RAM AT>FLASH + + .bss : + { + . = ALIGN(4); + PROVIDE( _sbss = .); + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss*) + *(.gnu.linkonce.b.*) + *(COMMON*) + . = ALIGN(4); + PROVIDE( _ebss = .); + } >RAM AT>FLASH + + PROVIDE( _end = _ebss); + PROVIDE( end = . ); + + .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = ALIGN(4); + PROVIDE(_susrstack = . ); + . = . + __stack_size; + PROVIDE( _eusrstack = .); + } >RAM + +} diff --git a/hw/bsp/ch32v10x/system_ch32v10x.c b/hw/bsp/ch32v10x/system_ch32v10x.c new file mode 100644 index 000000000..b083b83b4 --- /dev/null +++ b/hw/bsp/ch32v10x/system_ch32v10x.c @@ -0,0 +1,600 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : system_ch32v10x.c + * Author : WCH + * Version : V1.0.0 + * Date : 2020/04/30 + * Description : CH32V10x Device Peripheral Access Layer System Source File. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#include "ch32v10x.h" + +/* + * Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after + * reset the HSI is used as SYSCLK source). + * If none of the define below is enabled, the HSI is used as System clock source. + */ +//#define SYSCLK_FREQ_HSE HSE_VALUE +//#define SYSCLK_FREQ_48MHz_HSE 48000000 +//#define SYSCLK_FREQ_56MHz_HSE 56000000 +#define SYSCLK_FREQ_72MHz_HSE 72000000 +//#define SYSCLK_FREQ_HSI HSI_VALUE +//#define SYSCLK_FREQ_48MHz_HSI 48000000 +//#define SYSCLK_FREQ_56MHz_HSI 56000000 +//#define SYSCLK_FREQ_72MHz_HSI 72000000 + +/* Clock Definitions */ +#ifdef SYSCLK_FREQ_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_48MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_56MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_72MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_48MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_56MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_72MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */ +#else +uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */ + +#endif + +__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + +/* ch32v10x_system_private_function_proto_types */ +static void SetSysClock(void); + +#ifdef SYSCLK_FREQ_HSE +static void SetSysClockToHSE( void ); +#elif defined SYSCLK_FREQ_48MHz_HSE +static void SetSysClockTo48_HSE( void ); +#elif defined SYSCLK_FREQ_56MHz_HSE +static void SetSysClockTo56_HSE( void ); +#elif defined SYSCLK_FREQ_72MHz_HSE +static void SetSysClockTo72_HSE( void ); +#elif defined SYSCLK_FREQ_48MHz_HSI +static void SetSysClockTo48_HSI( void ); +#elif defined SYSCLK_FREQ_56MHz_HSI +static void SetSysClockTo56_HSI( void ); +#elif defined SYSCLK_FREQ_72MHz_HSI +static void SetSysClockTo72_HSI( void ); + +#endif + +/********************************************************************* + * @fn SystemInit + * + * @brief Setup the microcontroller system Initialize the Embedded Flash Interface, + * the PLL and update the SystemCoreClock variable. + * + * @return none + */ +void SystemInit(void) +{ + RCC->CTLR |= (uint32_t)0x00000001; + RCC->CFGR0 &= (uint32_t)0xF8FF0000; + RCC->CTLR &= (uint32_t)0xFEF6FFFF; + RCC->CTLR &= (uint32_t)0xFFFBFFFF; + RCC->CFGR0 &= (uint32_t)0xFF80FFFF; + RCC->INTR = 0x009F0000; + SetSysClock(); +} + +/********************************************************************* + * @fn SystemCoreClockUpdate + * + * @brief Update SystemCoreClock variable according to Clock Register Values. + * + * @return none + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0, pllmull = 0, pllsource = 0; + + tmp = RCC->CFGR0 & RCC_SWS; + + switch(tmp) + { + case 0x00: + SystemCoreClock = HSI_VALUE; + break; + case 0x04: + SystemCoreClock = HSE_VALUE; + break; + case 0x08: + pllmull = RCC->CFGR0 & RCC_PLLMULL; + pllsource = RCC->CFGR0 & RCC_PLLSRC; + pllmull = (pllmull >> 18) + 2; + if(pllsource == 0x00) + { + if( EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE ) + { + SystemCoreClock = ( HSI_VALUE ) * pllmull; + } + else + { + SystemCoreClock = ( HSI_VALUE >> 1 ) * pllmull; + } + } + else + { + if((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET) + { + SystemCoreClock = (HSE_VALUE >> 1) * pllmull; + } + else + { + SystemCoreClock = HSE_VALUE * pllmull; + } + } + break; + default: + SystemCoreClock = HSI_VALUE; + break; + } + + tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)]; + SystemCoreClock >>= tmp; +} + +/********************************************************************* + * @fn SetSysClock + * + * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClock(void) +{ + //GPIO_IPD_Unused(); +#ifdef SYSCLK_FREQ_HSE + SetSysClockToHSE(); +#elif defined SYSCLK_FREQ_48MHz_HSE + SetSysClockTo48_HSE(); +#elif defined SYSCLK_FREQ_56MHz_HSE + SetSysClockTo56_HSE(); +#elif defined SYSCLK_FREQ_72MHz_HSE + SetSysClockTo72_HSE(); +#elif defined SYSCLK_FREQ_48MHz_HSI + SetSysClockTo48_HSI(); +#elif defined SYSCLK_FREQ_56MHz_HSI + SetSysClockTo56_HSI(); +#elif defined SYSCLK_FREQ_72MHz_HSI + SetSysClockTo72_HSI(); + +#endif + + /* If none of the define above is enabled, the HSI is used as System clock + * source (default after reset) + */ +} + +#ifdef SYSCLK_FREQ_HSE + +/********************************************************************* + * @fn SetSysClockToHSE + * + * @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockToHSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if(HSEStatus == (uint32_t)0x01) + { + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + /* Flash 0 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_0; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1; + + /* Select HSE as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_HSE; + + /* Wait till HSE is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04) + { + } + } + else + { + /* If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + + +#elif defined SYSCLK_FREQ_48MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo48_HSE + * + * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo48_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if(HSEStatus == (uint32_t)0x01) + { + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 1 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL6); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_56MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo56_HSE + * + * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo56_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if(HSEStatus == (uint32_t)0x01) + { + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 2 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_2; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL7); + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_72MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo72_HSE + * + * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo72_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if(HSEStatus == (uint32_t)0x01) + { + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 2 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_2; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL9); + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_48MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo48_HSI + * + * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo48_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 1 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#elif defined SYSCLK_FREQ_56MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo56_HSI + * + * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo56_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 1 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 7 = 56 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#elif defined SYSCLK_FREQ_72MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo72_HSI + * + * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo72_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 1 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#endif diff --git a/hw/bsp/ch32v10x/system_ch32v10x.h b/hw/bsp/ch32v10x/system_ch32v10x.h new file mode 100644 index 000000000..d15624520 --- /dev/null +++ b/hw/bsp/ch32v10x/system_ch32v10x.h @@ -0,0 +1,29 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : system_ch32v10x.h + * Author : WCH + * Version : V1.0.0 + * Date : 2020/04/30 + * Description : CH32V10x Device Peripheral Access Layer System Header File. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __SYSTEM_CH32V10x_H +#define __SYSTEM_CH32V10x_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */ + +/* System_Exported_Functions */ +extern void SystemInit(void); +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__CH32V10x_SYSTEM_H */ diff --git a/hw/bsp/ch32v10x/wch-riscv.cfg b/hw/bsp/ch32v10x/wch-riscv.cfg new file mode 100644 index 000000000..aa35aa9c5 --- /dev/null +++ b/hw/bsp/ch32v10x/wch-riscv.cfg @@ -0,0 +1,17 @@ +adapter driver wlinke +adapter speed 6000 +transport select sdi + +wlink_set_address 0x00000000 +set _CHIPNAME wch_riscv +sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 + +set _TARGETNAME $_CHIPNAME.cpu + +target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME +$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1 +set _FLASHNAME $_CHIPNAME.flash + +flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 + +echo "Ready for Remote Connections" diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index daf3148f8..4485091dc 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -45,12 +45,12 @@ SRC_C += \ src/portable/wch/dcd_ch32_usbfs.c \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ $(SDK_SRC_DIR)/Core/core_riscv.c \ - $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_gpio.c \ - $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_misc.c \ - $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_rcc.c \ - $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_usart.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_misc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_rcc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_usart.c \ -SRC_S += $(SDK_SRC_DIR)/Startup/startup_ch32v20x_${MCU_VARIANT}.S +SRC_S += $(SDK_SRC_DIR)/Startup/startup_${CH32_FAMILY}_${MCU_VARIANT}.S INC += \ $(TOP)/$(BOARD_PATH) \ diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index d9443f811..94d55f04a 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -443,7 +443,7 @@ function(family_flash_openocd TARGET) # note skip verify since it has issue with rp2040 add_custom_target(${TARGET}-openocd DEPENDS ${TARGET} - COMMAND ${OPENOCD} ${OPTION_LIST} -c "program $ reset" ${OPTION_LIST2} -c exit + COMMAND ${OPENOCD} ${OPTION_LIST} -c init -c halt -c "program $ reset" ${OPTION_LIST2} -c exit VERBATIM ) endfunction() diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index c66996c4f..d9d11e96d 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -420,6 +420,15 @@ #define TUP_RHPORT_HIGHSPEED CFG_TUD_WCH_USBIP_USBHS #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_WCH_USBIP_USBHS ? 16 : 8) +#elif TU_CHECK_MCU(OPT_MCU_CH32V103) + #define TUP_USBIP_WCH_USBFS + + #if !defined(CFG_TUD_WCH_USBIP_USBFS) + #define CFG_TUD_WCH_USBIP_USBFS 1 + #endif + + #define TUP_DCD_ENDPOINT_MAX 8 + #elif TU_CHECK_MCU(OPT_MCU_CH32V20X) // v20x support both FSDEV (USBD) and USBFS, default to FSDEV #define TUP_USBIP_WCH_USBFS diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h index ef6ebf2dc..68be64f5e 100644 --- a/src/portable/wch/ch32_usbfs_reg.h +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -35,15 +35,68 @@ #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif -#if CFG_TUSB_MCU == OPT_MCU_CH32V307 - #include - #define USBHD_IRQn OTG_FS_IRQn - +#if CFG_TUSB_MCU == OPT_MCU_CH32F20X + #include +#elif CFG_TUSB_MCU == OPT_MCU_CH32V103 + #include + typedef struct + { + __IO uint8_t BASE_CTRL; + __IO uint8_t UDEV_CTRL; + __IO uint8_t INT_EN; + __IO uint8_t DEV_ADDR; + __IO uint8_t Reserve0; + __IO uint8_t MIS_ST; + __IO uint8_t INT_FG; + __IO uint8_t INT_ST; + __IO uint32_t RX_LEN; + __IO uint8_t UEP4_1_MOD; + __IO uint8_t UEP2_3_MOD; + __IO uint8_t UEP5_6_MOD; + __IO uint8_t UEP7_MOD; + __IO uint32_t UEP0_DMA; + __IO uint32_t UEP1_DMA; + __IO uint32_t UEP2_DMA; + __IO uint32_t UEP3_DMA; + __IO uint32_t UEP4_DMA; + __IO uint32_t UEP5_DMA; + __IO uint32_t UEP6_DMA; + __IO uint32_t UEP7_DMA; + __IO uint16_t UEP0_TX_LEN; + __IO uint8_t UEP0_TX_CTRL; + __IO uint8_t UEP0_RX_CTRL; + __IO uint16_t UEP1_TX_LEN; + __IO uint8_t UEP1_TX_CTRL; + __IO uint8_t UEP1_RX_CTRL; + __IO uint16_t UEP2_TX_LEN; + __IO uint8_t UEP2_TX_CTRL; + __IO uint8_t UEP2_RX_CTRL; + __IO uint16_t UEP3_TX_LEN; + __IO uint8_t UEP3_TX_CTRL; + __IO uint8_t UEP3_RX_CTRL; + __IO uint16_t UEP4_TX_LEN; + __IO uint8_t UEP4_TX_CTRL; + __IO uint8_t UEP4_RX_CTRL; + __IO uint16_t UEP5_TX_LEN; + __IO uint8_t UEP5_TX_CTRL; + __IO uint8_t UEP5_RX_CTRL; + __IO uint16_t UEP6_TX_LEN; + __IO uint8_t UEP6_TX_CTRL; + __IO uint8_t UEP6_RX_CTRL; + __IO uint16_t UEP7_TX_LEN; + __IO uint8_t UEP7_TX_CTRL; + __IO uint8_t UEP7_RX_CTRL; + __IO uint32_t Reserve1; + __IO uint32_t OTG_CR; + __IO uint32_t OTG_SR; + } USBOTG_FS_TypeDef; + + #define USBOTG_FS ((USBOTG_FS_TypeDef *) 0x40023400) #elif CFG_TUSB_MCU == OPT_MCU_CH32V20X #include - -#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X - #include +#elif CFG_TUSB_MCU == OPT_MCU_CH32V307 + #include + #define USBHD_IRQn OTG_FS_IRQn #endif #ifdef __GNUC__ diff --git a/src/tusb_option.h b/src/tusb_option.h index db8b94580..1ca09e902 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_OPTION_H_ -#define _TUSB_OPTION_H_ +#ifndef TUSB_OPTION_H_ +#define TUSB_OPTION_H_ #include "common/tusb_compiler.h" @@ -182,7 +182,7 @@ #define OPT_MCU_CH32V307 2200 ///< WCH CH32V307 #define OPT_MCU_CH32F20X 2210 ///< WCH CH32F20x #define OPT_MCU_CH32V20X 2220 ///< WCH CH32V20X - +#define OPT_MCU_CH32V103 2230 ///< WCH CH32V103 // NXP LPC MCX #define OPT_MCU_MCXN9 2300 ///< NXP MCX N9 Series diff --git a/tools/get_deps.py b/tools/get_deps.py index 50cc5c893..92bfb86a2 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -168,6 +168,9 @@ deps_optional = { 'hw/mcu/ti': ['https://github.com/hathach/ti_driver.git', '143ed6cc20a7615d042b03b21e070197d473e6e5', 'msp430 msp432e4 tm4c'], + 'hw/mcu/wch/ch32v103': ['https://github.com/openwch/ch32v103.git', + '7578cae0b21f86dd053a1f781b2fc6ab99d0ec17', + 'ch32v10x'], 'hw/mcu/wch/ch32v20x': ['https://github.com/openwch/ch32v20x.git', 'de6d68c654340d7f27b00cebbfc9aa2740a1abc2', 'ch32v20x'], -- cgit v1.3.1 From 9ae00535737f6f442a9ca7ad3167f686c0d557b1 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 16:08:26 +0700 Subject: newline --- src/portable/st/stm32_fsdev/fsdev_ch32.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h index dbf2a0289..f63a80d56 100644 --- a/src/portable/st/stm32_fsdev/fsdev_ch32.h +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -43,10 +43,10 @@ #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif -#if CFG_TUSB_MCU == OPT_MCU_CH32V20X - #include -#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X +#if CFG_TUSB_MCU == OPT_MCU_CH32F20X #include +#elif CFG_TUSB_MCU == OPT_MCU_CH32V20X + #include #endif #ifdef __GNUC__ -- cgit v1.3.1 From 5e9ad7daeef83bf2d2079b25cedd6bcafcd30023 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 16:09:08 +0700 Subject: add ch32v10x to ci build --- .github/workflows/ci_set_matrix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 7dc9a2fa1..5584b8312 100644 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -15,7 +15,7 @@ toolchain_list = { family_list = { "broadcom_32bit": ["arm-gcc"], "broadcom_64bit": ["aarch64-gcc"], - "ch32v20x ch32v307 fomu gd32vf103": ["riscv-gcc"], + "ch32v10x ch32v20x ch32v307 fomu gd32vf103": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"], "lpc11 lpc13 lpc15": ["arm-gcc", "arm-clang"], -- cgit v1.3.1 From f32851cf2ae6ec7aa3b39150c3f0f96d65af9b3a Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 16:16:10 +0700 Subject: fix ci skip example for ch32v1 --- examples/device/audio_4_channel_mic_freertos/skip.txt | 1 + examples/device/audio_test_freertos/skip.txt | 1 + examples/device/cdc_msc_freertos/skip.txt | 1 + examples/device/hid_composite_freertos/skip.txt | 1 + examples/device/net_lwip_webserver/skip.txt | 1 + examples/device/video_capture/skip.txt | 1 + examples/device/video_capture_2ch/skip.txt | 1 + src/tusb_option.h | 4 ++-- 8 files changed, 9 insertions(+), 2 deletions(-) diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt index 4769af009..012ca4e74 100644 --- a/examples/device/audio_4_channel_mic_freertos/skip.txt +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:CXD56 diff --git a/examples/device/audio_test_freertos/skip.txt b/examples/device/audio_test_freertos/skip.txt index 6aaa27661..c13667f56 100644 --- a/examples/device/audio_test_freertos/skip.txt +++ b/examples/device/audio_test_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:CXD56 diff --git a/examples/device/cdc_msc_freertos/skip.txt b/examples/device/cdc_msc_freertos/skip.txt index 457ddb760..75a79aff4 100644 --- a/examples/device/cdc_msc_freertos/skip.txt +++ b/examples/device/cdc_msc_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:CXD56 diff --git a/examples/device/hid_composite_freertos/skip.txt b/examples/device/hid_composite_freertos/skip.txt index 6aaa27661..c13667f56 100644 --- a/examples/device/hid_composite_freertos/skip.txt +++ b/examples/device/hid_composite_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:CXD56 diff --git a/examples/device/net_lwip_webserver/skip.txt b/examples/device/net_lwip_webserver/skip.txt index 51af58667..85c450e82 100644 --- a/examples/device/net_lwip_webserver/skip.txt +++ b/examples/device/net_lwip_webserver/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V103 mcu:CH32V20X mcu:LPC11UXX mcu:LPC13XX diff --git a/examples/device/video_capture/skip.txt b/examples/device/video_capture/skip.txt index 714cabeec..cb0c7d2e6 100644 --- a/examples/device/video_capture/skip.txt +++ b/examples/device/video_capture/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V103 mcu:CH32V20X mcu:MSP430x5xx mcu:NUC121 diff --git a/examples/device/video_capture_2ch/skip.txt b/examples/device/video_capture_2ch/skip.txt index 1786297f9..af3b0de04 100644 --- a/examples/device/video_capture_2ch/skip.txt +++ b/examples/device/video_capture_2ch/skip.txt @@ -2,6 +2,7 @@ mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 mcu:GD32VF103 +mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:STM32L0 diff --git a/src/tusb_option.h b/src/tusb_option.h index 1ca09e902..8990cf92b 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef TUSB_OPTION_H_ -#define TUSB_OPTION_H_ +#ifndef _TUSB_OPTION_H_ +#define _TUSB_OPTION_H_ #include "common/tusb_compiler.h" -- cgit v1.3.1 From e1012997f06c5d857de995870cd989be22187ffb Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 16:55:46 +0700 Subject: more update --- hw/bsp/ch32v10x/family.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/bsp/ch32v10x/family.c b/hw/bsp/ch32v10x/family.c index 6de17521e..c41b207e0 100644 --- a/hw/bsp/ch32v10x/family.c +++ b/hw/bsp/ch32v10x/family.c @@ -68,6 +68,9 @@ void board_init(void) { SysTick_Config(SystemCoreClock / 1000); #endif + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); + + EXTEN->EXTEN_CTR |= EXTEN_USBFS_IO_EN; uint8_t usb_div; switch (SystemCoreClock) { case 48000000: usb_div = RCC_USBCLKSource_PLLCLK_Div1; break; @@ -75,9 +78,7 @@ void board_init(void) { default: TU_ASSERT(0,); break; } RCC_USBCLKConfig(usb_div); - RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); - - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBFS, ENABLE); #ifdef LED_PIN GPIO_InitTypeDef led_init = { -- cgit v1.3.1 From 2be72a97b8fd4d08ca20a9b8815f2042c4ef7520 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 17:55:36 +0700 Subject: minor update --- hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk | 2 -- hw/bsp/ch32v10x/family.c | 2 +- src/class/net/ncm_device.c | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk index 7d7462312..70e65333c 100644 --- a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk +++ b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk @@ -1,5 +1,3 @@ -MCU_VARIANT = D6 - CFLAGS += -DCFG_EXAMPLE_MSC_DUAL_READONLY LDFLAGS += \ diff --git a/hw/bsp/ch32v10x/family.c b/hw/bsp/ch32v10x/family.c index c41b207e0..15f754e11 100644 --- a/hw/bsp/ch32v10x/family.c +++ b/hw/bsp/ch32v10x/family.c @@ -24,7 +24,7 @@ void USBHD_IRQHandler(void) { } __attribute__((interrupt)) __attribute__((used)) -void USBHDWakeUp_IRQHandler(void) { +void USBWakeUp_IRQHandler(void) { #if CFG_TUD_WCH_USBIP_USBFS tud_int_handler(0); #endif diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 44a6a0de9..90d747185 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -1,10 +1,10 @@ /* * The MIT License (MIT) * - * Copyright (c) 2020 Jacob Berg Potter - * Copyright (c) 2020 Peter Lawrence * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2024 Hardy Griech + * Copyright (c) 2020 Jacob Berg Potter + * Copyright (c) 2020 Peter Lawrence * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal -- cgit v1.3.1 From 00062ddb0cda4e46750c7df09aa31026cc03b5ee Mon Sep 17 00:00:00 2001 From: Okarss <104319900+Okarss@users.noreply.github.com> Date: Fri, 14 Jun 2024 18:16:09 +0300 Subject: [STM32 FSDEV] Simplify toggle bit logic --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 12 ++++++------ src/portable/st/stm32_fsdev/fsdev_common.h | 24 ++---------------------- 2 files changed, 8 insertions(+), 28 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 9ce37f992..b5b89c577 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -215,20 +215,20 @@ void dcd_init(uint8_t rhport) /* The RM mentions to use a special ordering of PDWN and FRES, but this isn't done in HAL. * Here, the RM is followed. */ - for (uint32_t i = 0; i < 200; i++) { // should be a few us - asm("NOP"); + for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us + __DSB(); } // Perform USB peripheral reset USB->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; - for (uint32_t i = 0; i < 200; i++) { // should be a few us - asm("NOP"); + for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us + __DSB(); } USB->CNTR &= ~USB_CNTR_PDWN; // Wait startup time, for F042 and F070, this is <= 1 us. - for (uint32_t i = 0; i < 200; i++) { // should be a few us - asm("NOP"); + for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us + __DSB(); } USB->CNTR = 0; // Enable USB diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index af5d8afab..e8a6af8cb 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -295,18 +295,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, u TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPTX_DTOGMASK; - - /* toggle first bit ? */ - if((USB_EPTX_DTOG1 & (wState))!= 0U) - { - regVal ^= USB_EPTX_DTOG1; - } - /* toggle second bit ? */ - if((USB_EPTX_DTOG2 & ((uint32_t)(wState)))!= 0U) - { - regVal ^= USB_EPTX_DTOG2; - } - + regVal ^= wState; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; pcd_set_endpoint(USBx, bEpIdx, regVal); } @@ -322,16 +311,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPRX_DTOGMASK; - - /* toggle first bit ? */ - if((USB_EPRX_DTOG1 & wState)!= 0U) { - regVal ^= USB_EPRX_DTOG1; - } - /* toggle second bit ? */ - if((USB_EPRX_DTOG2 & wState)!= 0U) { - regVal ^= USB_EPRX_DTOG2; - } - + regVal ^= wState; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; pcd_set_endpoint(USBx, bEpIdx, regVal); } -- cgit v1.3.1 From fb6a6acbff81a98e37b86a0dc3370d4076bb356c Mon Sep 17 00:00:00 2001 From: Okarss <104319900+Okarss@users.noreply.github.com> Date: Fri, 14 Jun 2024 18:39:48 +0300 Subject: Revert the DSB because of RISC-V --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index b5b89c577..4e31c99fa 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -216,19 +216,19 @@ void dcd_init(uint8_t rhport) * Here, the RM is followed. */ for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us - __DSB(); + asm("NOP"); } // Perform USB peripheral reset USB->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us - __DSB(); + asm("NOP"); } USB->CNTR &= ~USB_CNTR_PDWN; // Wait startup time, for F042 and F070, this is <= 1 us. for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us - __DSB(); + asm("NOP"); } USB->CNTR = 0; // Enable USB -- cgit v1.3.1 From 5f060a357d34257f5a742ebf78c5e4e0873c7a13 Mon Sep 17 00:00:00 2001 From: Okarss <104319900+Okarss@users.noreply.github.com> Date: Fri, 14 Jun 2024 21:23:17 +0300 Subject: Update the STM32 documentation --- README.rst | 5 +++-- docs/reference/supported.rst | 20 +++++++++++++++++--- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 10 ++++++++-- src/portable/st/stm32_fsdev/fsdev_stm32.h | 2 +- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/README.rst b/README.rst index b5f9fc149..1ae8c5375 100644 --- a/README.rst +++ b/README.rst @@ -151,8 +151,9 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l +--------------+------------------------------------------------------------+ | Sony | CXD56 | +--------------+------------------------------------------------------------+ -| ST STM32 | F0, F1, F2, F3, F4, F7, H5, H7, G0, G4, L0, L1, L4, L4+, | -| | U5, WB | +| ST STM32 | F0, F1, F2, F3, F4, F7, G0, G4, H5, H7, | +| | | +| | L0, L1, L4, L4+, L5, U5, WB | +--------------+------------------------------------------------------------+ | TI | MSP430, MSP432E4, TM4C123 | +--------------+------------------------------------------------------------+ diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 3ca203e88..d0e0bf1af 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -104,11 +104,17 @@ Supported MCUs | +-----------------------+--------+------+-----------+-------------------+--------------+ | | F7 | ✔ | | ✔ | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | H7 | ✔ | | ✔ | dwc2 | | +| | G0 | ✔ | ✖ | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ | | G4 | ✔ | ✖ | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | L0, L1 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | H5 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | H7 | ✔ | | ✔ | dwc2 | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | L0 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | L1 | ✔ | ✖ | ✖ | stm32_fsdev | | | +----+------------------+--------+------+-----------+-------------------+--------------+ | | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | | | | +------------------+--------+------+-----------+-------------------+--------------+ @@ -116,8 +122,14 @@ Supported MCUs | +----+------------------+--------+------+-----------+-------------------+--------------+ | | L4+ | ✔ | | | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | U5 | ✔ | | ✔ | dwc2 | | +| | L5 | ✔ | ✖ | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ +| | U5 | 535, 545 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | +------------------+--------+------+-----------+-------------------+--------------+ +| | | 575, 585 | ✔ | | ✖ | dwc2 | | +| | +------------------+--------+------+-----------+-------------------+--------------+ +| | | 59x,5Ax,5Fx,5Gx | ✔ | | ✔ | dwc2 | | +| +----+------------------+--------+------+-----------+-------------------+--------------+ | | WBx5 | ✔ | | | stm32_fsdev | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | @@ -129,7 +141,9 @@ Supported MCUs | ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | WCH | CH32F20x | ✔ | | ✔ | ch32f205 | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ | | CH32V20x | ✔ | | ✖ | ch32v20x | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ | | CH32V307 | ✔ | | ✔ | ch32v307 | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 9ce37f992..0ecb6ea05 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -37,14 +37,20 @@ * It also should work with minimal changes for any ST MCU with an "USB A"/"PCD"/"HCD" peripheral. This * covers: * - * F04x, F072, F078, 070x6/B 1024 byte buffer + * F04x, F072, F078, F070x6/B 1024 byte buffer * F102, F103 512 byte buffer; no internal D+ pull-up (maybe many more changes?) * F302xB/C, F303xB/C, F373 512 byte buffer; no internal D+ pull-up * F302x6/8, F302xD/E2, F303xD/E 1024 byte buffer; no internal D+ pull-up + * G0 2048 byte buffer; 32-bit bus + * G4 1024 byte buffer + * H5 2048 byte buffer; 32-bit bus * L0x2, L0x3 1024 byte buffer * L1 512 byte buffer * L4x2, L4x3 1024 byte buffer - * G0 2048 byte buffer + * L5 1024 byte buffer + * U0 1024 byte buffer; 32-bit bus + * U535, U545 2048 byte buffer; 32-bit bus + * WB35, WB55 1024 byte buffer * * To use this driver, you must: * - If you are using a device with crystal-less USB, set up the clock recovery system (CRS) diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index b3fa11b88..524efc75f 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -161,7 +161,7 @@ #else #error You are using an untested or unimplemented STM32 variant. Please update the driver. - // This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4 + // This includes U0 #endif // This checks if the device has "LPM" -- cgit v1.3.1 From d52d659261bd2bd680bdb5194bfd11349a2ed994 Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Tue, 18 Jun 2024 14:02:36 +0930 Subject: usbh: Set interface recipient should be interface --- src/host/usbh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 7a47f5056..a94c22c4c 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1113,7 +1113,7 @@ bool tuh_interface_set(uint8_t daddr, uint8_t itf_num, uint8_t itf_alt, TU_LOG_USBH("Set Interface %u Alternate %u\r\n", itf_num, itf_alt); tusb_control_request_t const request = { .bmRequestType_bit = { - .recipient = TUSB_REQ_RCPT_DEVICE, + .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_OUT }, -- cgit v1.3.1 From f93eb40b1d9f52ec4b8557e190ad64b3588c63c9 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 18 Jun 2024 12:52:32 +0700 Subject: add host/device_info example --- examples/dual/host_hid_to_device_cdc/src/main.c | 107 +++++------ .../dual/host_hid_to_device_cdc/src/tusb_config.h | 6 +- .../host_hid_to_device_cdc/src/usb_descriptors.c | 98 +++++----- examples/host/CMakeLists.txt | 1 + examples/host/bare_api/src/main.c | 4 - examples/host/bare_api/src/tusb_config.h | 6 +- examples/host/device_info/CMakeLists.txt | 32 ++++ examples/host/device_info/Makefile | 13 ++ examples/host/device_info/only.txt | 14 ++ examples/host/device_info/src/main.c | 211 +++++++++++++++++++++ examples/host/device_info/src/tusb_config.h | 115 +++++++++++ 11 files changed, 479 insertions(+), 128 deletions(-) create mode 100644 examples/host/device_info/CMakeLists.txt create mode 100644 examples/host/device_info/Makefile create mode 100644 examples/host/device_info/only.txt create mode 100644 examples/host/device_info/src/main.c create mode 100644 examples/host/device_info/src/tusb_config.h diff --git a/examples/dual/host_hid_to_device_cdc/src/main.c b/examples/dual/host_hid_to_device_cdc/src/main.c index 96a2beff5..0b4165e38 100644 --- a/examples/dual/host_hid_to_device_cdc/src/main.c +++ b/examples/dual/host_hid_to_device_cdc/src/main.c @@ -55,14 +55,14 @@ const uint8_t colemak[128] = { }; #endif -static uint8_t const keycode2ascii[128][2] = { HID_KEYCODE_TO_ASCII }; +static uint8_t const keycode2ascii[128][2] = {HID_KEYCODE_TO_ASCII}; /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ -enum { +enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, @@ -73,8 +73,7 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); /*------------- MAIN -------------*/ -int main(void) -{ +int main(void) { board_init(); printf("TinyUSB Host HID <-> Device CDC Example\r\n"); @@ -87,8 +86,7 @@ int main(void) board_init_after_tusb(); } - while (1) - { + while (1) { tud_task(); // tinyusb device task tuh_task(); // tinyusb host task led_blinking_task(); @@ -102,35 +100,30 @@ int main(void) //--------------------------------------------------------------------+ // Invoked when device is mounted -void tud_mount_cb(void) -{ +void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted -void tud_umount_cb(void) -{ +void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus -void tud_suspend_cb(bool remote_wakeup_en) -{ +void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed -void tud_resume_cb(void) -{ +void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } // Invoked when CDC interface received data from host -void tud_cdc_rx_cb(uint8_t itf) -{ +void tud_cdc_rx_cb(uint8_t itf) { (void) itf; char buf[64]; @@ -149,38 +142,36 @@ void tud_cdc_rx_cb(uint8_t itf) // can be used to parse common/simple enough descriptor. // Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped // therefore report_desc = NULL, desc_len = 0 -void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) -{ - (void)desc_report; - (void)desc_len; +void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { + (void) desc_report; + (void) desc_len; // Interface protocol (hid_interface_protocol_enum_t) - const char* protocol_str[] = { "None", "Keyboard", "Mouse" }; + const char* protocol_str[] = {"None", "Keyboard", "Mouse"}; uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); uint16_t vid, pid; tuh_vid_pid_get(dev_addr, &vid, &pid); char tempbuf[256]; - int count = sprintf(tempbuf, "[%04x:%04x][%u] HID Interface%u, Protocol = %s\r\n", vid, pid, dev_addr, instance, protocol_str[itf_protocol]); + int count = sprintf( + tempbuf, "[%04x:%04x][%u] HID Interface%u, Protocol = %s\r\n", vid, pid, dev_addr, instance, + protocol_str[itf_protocol]); tud_cdc_write(tempbuf, (uint32_t) count); tud_cdc_write_flush(); // Receive report from boot keyboard & mouse only // tuh_hid_report_received_cb() will be invoked when report is available - if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD || itf_protocol == HID_ITF_PROTOCOL_MOUSE) - { - if ( !tuh_hid_receive_report(dev_addr, instance) ) - { + if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD || itf_protocol == HID_ITF_PROTOCOL_MOUSE) { + if (!tuh_hid_receive_report(dev_addr, instance)) { tud_cdc_write_str("Error: cannot request report\r\n"); } } } // Invoked when device with hid interface is un-mounted -void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) -{ +void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { char tempbuf[256]; int count = sprintf(tempbuf, "[%u] HID Interface%u is unmounted\r\n", dev_addr, instance); tud_cdc_write(tempbuf, (uint32_t) count); @@ -188,11 +179,9 @@ void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) } // look up new key in previous keys -static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8_t keycode) -{ - for(uint8_t i=0; i<6; i++) - { - if (report->keycode[i] == keycode) return true; +static inline bool find_key_in_report(hid_keyboard_report_t const* report, uint8_t keycode) { + for (uint8_t i = 0; i < 6; i++) { + if (report->keycode[i] == keycode) return true; } return false; @@ -200,22 +189,17 @@ static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8 // convert hid keycode to ascii and print via usb device CDC (ignore non-printable) -static void process_kbd_report(uint8_t dev_addr, hid_keyboard_report_t const *report) -{ +static void process_kbd_report(uint8_t dev_addr, hid_keyboard_report_t const* report) { (void) dev_addr; - static hid_keyboard_report_t prev_report = { 0, 0, {0} }; // previous report to check key released + static hid_keyboard_report_t prev_report = {0, 0, {0}}; // previous report to check key released bool flush = false; - for(uint8_t i=0; i<6; i++) - { + for (uint8_t i = 0; i < 6; i++) { uint8_t keycode = report->keycode[i]; - if ( keycode ) - { - if ( find_key_in_report(&prev_report, keycode) ) - { + if (keycode) { + if (find_key_in_report(&prev_report, keycode)) { // exist in previous report means the current key is holding - }else - { + } else { // not existed in previous report means the current key is pressed // remap the key code for Colemak layout @@ -227,8 +211,7 @@ static void process_kbd_report(uint8_t dev_addr, hid_keyboard_report_t const *re bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT); uint8_t ch = keycode2ascii[keycode][is_shift ? 1 : 0]; - if (ch) - { + if (ch) { if (ch == '\n') tud_cdc_write("\r", 1); tud_cdc_write(&ch, 1); flush = true; @@ -244,13 +227,12 @@ static void process_kbd_report(uint8_t dev_addr, hid_keyboard_report_t const *re } // send mouse report to usb device CDC -static void process_mouse_report(uint8_t dev_addr, hid_mouse_report_t const * report) -{ +static void process_mouse_report(uint8_t dev_addr, hid_mouse_report_t const* report) { //------------- button state -------------// //uint8_t button_changed_mask = report->buttons ^ prev_report.buttons; - char l = report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-'; + char l = report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-'; char m = report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-'; - char r = report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-'; + char r = report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-'; char tempbuf[32]; int count = sprintf(tempbuf, "[%u] %c%c%c %d %d %d\r\n", dev_addr, l, m, r, report->x, report->y, report->wheel); @@ -260,27 +242,25 @@ static void process_mouse_report(uint8_t dev_addr, hid_mouse_report_t const * re } // Invoked when received report from device via interrupt endpoint -void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) -{ +void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) { (void) len; uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); - switch(itf_protocol) - { + switch (itf_protocol) { case HID_ITF_PROTOCOL_KEYBOARD: - process_kbd_report(dev_addr, (hid_keyboard_report_t const*) report ); - break; + process_kbd_report(dev_addr, (hid_keyboard_report_t const*) report); + break; case HID_ITF_PROTOCOL_MOUSE: - process_mouse_report(dev_addr, (hid_mouse_report_t const*) report ); - break; + process_mouse_report(dev_addr, (hid_mouse_report_t const*) report); + break; - default: break; + default: + break; } // continue to request to receive report - if ( !tuh_hid_receive_report(dev_addr, instance) ) - { + if (!tuh_hid_receive_report(dev_addr, instance)) { tud_cdc_write_str("Error: cannot request report\r\n"); } } @@ -288,13 +268,12 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ -void led_blinking_task(void) -{ +void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + if (board_millis() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/dual/host_hid_to_device_cdc/src/tusb_config.h b/examples/dual/host_hid_to_device_cdc/src/tusb_config.h index 8133ed418..2843e0b83 100644 --- a/examples/dual/host_hid_to_device_cdc/src/tusb_config.h +++ b/examples/dual/host_hid_to_device_cdc/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -144,4 +144,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif diff --git a/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c b/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c index 293620042..9d57737fb 100644 --- a/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c +++ b/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c @@ -42,44 +42,41 @@ //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = -{ - .bLength = sizeof(tusb_desc_device_t), - .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = USB_BCD, +tusb_desc_device_t const desc_device = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = USB_BCD, - // Use Interface Association Descriptor (IAD) for CDC - // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) - .bDeviceClass = TUSB_CLASS_MISC, - .bDeviceSubClass = MISC_SUBCLASS_COMMON, - .bDeviceProtocol = MISC_PROTOCOL_IAD, + // Use Interface Association Descriptor (IAD) for CDC + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, - .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - .idVendor = USB_VID, - .idProduct = USB_PID, - .bcdDevice = 0x0100, + .idVendor = USB_VID, + .idProduct = USB_PID, + .bcdDevice = 0x0100, - .iManufacturer = 0x01, - .iProduct = 0x02, - .iSerialNumber = 0x03, + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, - .bNumConfigurations = 0x01 + .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor -uint8_t const * tud_descriptor_device_cb(void) -{ - return (uint8_t const *) &desc_device; +uint8_t const* tud_descriptor_device_cb(void) { + return (uint8_t const*) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ -enum -{ +enum { ITF_NUM_CDC = 0, ITF_NUM_CDC_DATA, ITF_NUM_TOTAL @@ -92,7 +89,7 @@ enum #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 -#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X +#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 @@ -109,7 +106,7 @@ enum #define EPNUM_CDC_IN 0x81 #elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X - // FT9XX doesn't support a same endpoint number with different direction IN and OUT +// FT9XX doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 @@ -125,21 +122,19 @@ enum #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN) // full speed configuration -uint8_t const desc_fs_configuration[] = -{ - // Config number, interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), +uint8_t const desc_fs_configuration[] = { + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), - // Interface number, string index, EP notification address and size, EP data address (out, in) and size. - TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), + // Interface number, string index, EP notification address and size, EP data address (out, in) and size. + TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), }; #if TUD_OPT_HIGH_SPEED // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // high speed configuration -uint8_t const desc_hs_configuration[] = -{ +uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -151,8 +146,7 @@ uint8_t const desc_hs_configuration[] = uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed -tusb_desc_device_qualifier_t const desc_device_qualifier = -{ +tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, @@ -170,16 +164,14 @@ tusb_desc_device_qualifier_t const desc_device_qualifier = // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. -uint8_t const* tud_descriptor_device_qualifier_cb(void) -{ +uint8_t const* tud_descriptor_device_qualifier_cb(void) { return (uint8_t const*) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa -uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) -{ +uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index; // for multiple configurations // if link speed is high return fullspeed config, and vice versa @@ -199,8 +191,7 @@ uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete -uint8_t const * tud_descriptor_configuration_cb(uint8_t index) -{ +uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED @@ -224,24 +215,23 @@ enum { }; // array of pointer to string descriptors -char const *string_desc_arr[] = -{ - (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) - "TinyUSB", // 1: Manufacturer - "TinyUSB Device", // 2: Product - NULL, // 3: Serials will use unique ID if possible - "TinyUSB CDC", // 4: CDC Interface +char const* string_desc_arr[] = { + (const char[]) {0x09, 0x04}, // 0: is supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + NULL, // 3: Serials will use unique ID if possible + "TinyUSB CDC", // 4: CDC Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete -uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { +uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; - switch ( index ) { + switch (index) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; @@ -255,17 +245,17 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) return NULL; - const char *str = string_desc_arr[index]; + const char* str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type - if ( chr_count > max_count ) chr_count = max_count; + if (chr_count > max_count) chr_count = max_count; // Convert ASCII string into UTF-16 - for ( size_t i = 0; i < chr_count; i++ ) { + for (size_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } break; diff --git a/examples/host/CMakeLists.txt b/examples/host/CMakeLists.txt index e6a2ece14..793f6ab08 100644 --- a/examples/host/CMakeLists.txt +++ b/examples/host/CMakeLists.txt @@ -9,5 +9,6 @@ family_initialize_project(tinyusb_host_examples ${CMAKE_CURRENT_LIST_DIR}) family_add_subdirectory(bare_api) family_add_subdirectory(cdc_msc_hid) family_add_subdirectory(cdc_msc_hid_freertos) +family_add_subdirectory(device_info) family_add_subdirectory(hid_controller) family_add_subdirectory(msc_file_explorer) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 670e58498..ae574c078 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -23,10 +23,6 @@ * */ -/* This example current worked and tested with following controller - * - Sony DualShock 4 [CUH-ZCT2x] VID = 0x054c, PID = 0x09cc - */ - #include #include diff --git a/examples/host/bare_api/src/tusb_config.h b/examples/host/bare_api/src/tusb_config.h index 432446e94..fab233be0 100644 --- a/examples/host/bare_api/src/tusb_config.h +++ b/examples/host/bare_api/src/tusb_config.h @@ -23,8 +23,8 @@ * */ -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { @@ -118,4 +118,4 @@ } #endif -#endif /* _TUSB_CONFIG_H_ */ +#endif diff --git a/examples/host/device_info/CMakeLists.txt b/examples/host/device_info/CMakeLists.txt new file mode 100644 index 000000000..76182d6fa --- /dev/null +++ b/examples/host/device_info/CMakeLists.txt @@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 3.17) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) + +# gets PROJECT name for the example +family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) + +project(${PROJECT} C CXX ASM) + +# Checks this example is valid for the family and initializes the project +family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) + +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + +add_executable(${PROJECT}) + +# Example source +target_sources(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ) + +# Example include +target_include_directories(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src + ) + +# Configure compilation flags and libraries for the example without RTOS. +# See the corresponding function in hw/bsp/FAMILY/family.cmake for details. +family_configure_host_example(${PROJECT} noos) diff --git a/examples/host/device_info/Makefile b/examples/host/device_info/Makefile new file mode 100644 index 000000000..0235e08c3 --- /dev/null +++ b/examples/host/device_info/Makefile @@ -0,0 +1,13 @@ +include ../../build_system/make/make.mk + +INC += \ + src \ + $(TOP)/hw \ + +# Example source +EXAMPLE_SOURCE += \ + src/main.c + +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +include ../../build_system/make/rules.mk diff --git a/examples/host/device_info/only.txt b/examples/host/device_info/only.txt new file mode 100644 index 000000000..fee10f9e2 --- /dev/null +++ b/examples/host/device_info/only.txt @@ -0,0 +1,14 @@ +mcu:KINETIS_KL +mcu:LPC175X_6X +mcu:LPC177X_8X +mcu:LPC18XX +mcu:LPC40XX +mcu:LPC43XX +mcu:MIMXRT1XXX +mcu:MIMXRT10XX +mcu:MIMXRT11XX +mcu:RP2040 +mcu:MSP432E4 +mcu:RX65X +mcu:RAXXX +mcu:MAX3421 diff --git a/examples/host/device_info/src/main.c b/examples/host/device_info/src/main.c new file mode 100644 index 000000000..60d7e9c80 --- /dev/null +++ b/examples/host/device_info/src/main.c @@ -0,0 +1,211 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +/* Host example will get device descriptors of attached devices and print it out via + * device cdc (Serial) as follows: + * Device 1: ID 046d:c52f + Device Descriptor: + bLength 18 + bDescriptorType 1 + bcdUSB 0200 + bDeviceClass 0 + bDeviceSubClass 0 + bDeviceProtocol 0 + bMaxPacketSize0 8 + idVendor 0x046d + idProduct 0xc52f + bcdDevice 2200 + iManufacturer 1 Logitech + iProduct 2 USB Receiver + iSerialNumber 0 + bNumConfigurations 1 + * + */ + +#include +#include +#include + +#include "bsp/board_api.h" +#include "tusb.h" + +// English +#define LANGUAGE_ID 0x0409 + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ +void led_blinking_task(void); +static void print_utf16(uint16_t* temp_buf, size_t buf_len); + +/*------------- MAIN -------------*/ +int main(void) { + board_init(); + + printf("TinyUSB Device Info Example\r\n"); + + // init host stack on configured roothub port + tuh_init(BOARD_TUH_RHPORT); + + if (board_init_after_tusb) { + board_init_after_tusb(); + } + + while (1) { + // tinyusb host task + tuh_task(); + led_blinking_task(); + } + + return 0; +} + +/*------------- TinyUSB Callbacks -------------*/ + +// Invoked when device is mounted (configured) +void tuh_mount_cb(uint8_t daddr) { + // Get Device Descriptor + tusb_desc_device_t desc_device; + uint8_t xfer_result = tuh_descriptor_get_device_sync(daddr, &desc_device, 18); + if (XFER_RESULT_SUCCESS != xfer_result) { + printf("Failed to get device descriptor\r\n"); + return; + } + + uint16_t buf[256]; + + printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct); + printf("Device Descriptor:\r\n"); + printf(" bLength %u\r\n", desc_device.bLength); + printf(" bDescriptorType %u\r\n", desc_device.bDescriptorType); + printf(" bcdUSB %04x\r\n", desc_device.bcdUSB); + printf(" bDeviceClass %u\r\n", desc_device.bDeviceClass); + printf(" bDeviceSubClass %u\r\n", desc_device.bDeviceSubClass); + printf(" bDeviceProtocol %u\r\n", desc_device.bDeviceProtocol); + printf(" bMaxPacketSize0 %u\r\n", desc_device.bMaxPacketSize0); + printf(" idVendor 0x%04x\r\n", desc_device.idVendor); + printf(" idProduct 0x%04x\r\n", desc_device.idProduct); + printf(" bcdDevice %04x\r\n", desc_device.bcdDevice); + + // Get String descriptor using Sync API + + printf(" iManufacturer %u ", desc_device.iManufacturer); + xfer_result = tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf)); + if (XFER_RESULT_SUCCESS == xfer_result) { + print_utf16(buf, TU_ARRAY_SIZE(buf)); + } + printf("\r\n"); + + printf(" iProduct %u ", desc_device.iProduct); + xfer_result = tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf)); + if (XFER_RESULT_SUCCESS == xfer_result) { + print_utf16(buf, TU_ARRAY_SIZE(buf)); + } + printf("\r\n"); + + printf(" iSerialNumber %u ", desc_device.iSerialNumber); + xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf)); + if (XFER_RESULT_SUCCESS == xfer_result) { + print_utf16(buf, TU_ARRAY_SIZE(buf)); + } + printf("\r\n"); + + printf(" bNumConfigurations %u\r\n", desc_device.bNumConfigurations); +} + +/// Invoked when device is unmounted (bus reset/unplugged) +void tuh_umount_cb(uint8_t daddr) { + printf("Device removed, address = %d\r\n", daddr); +} + +//--------------------------------------------------------------------+ +// Blinking Task +//--------------------------------------------------------------------+ +void led_blinking_task(void) { + const uint32_t interval_ms = 1000; + static uint32_t start_ms = 0; + + static bool led_state = false; + + // Blink every interval ms + if (board_millis() - start_ms < interval_ms) return; // not enough time + start_ms += interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle +} + +//--------------------------------------------------------------------+ +// String Descriptor Helper +//--------------------------------------------------------------------+ + +static void _convert_utf16le_to_utf8(const uint16_t* utf16, size_t utf16_len, uint8_t* utf8, size_t utf8_len) { + // TODO: Check for runover. + (void) utf8_len; + // Get the UTF-16 length out of the data itself. + + for (size_t i = 0; i < utf16_len; i++) { + uint16_t chr = utf16[i]; + if (chr < 0x80) { + *utf8++ = chr & 0xffu; + } else if (chr < 0x800) { + *utf8++ = (uint8_t) (0xC0 | (chr >> 6 & 0x1F)); + *utf8++ = (uint8_t) (0x80 | (chr >> 0 & 0x3F)); + } else { + // TODO: Verify surrogate. + *utf8++ = (uint8_t) (0xE0 | (chr >> 12 & 0x0F)); + *utf8++ = (uint8_t) (0x80 | (chr >> 6 & 0x3F)); + *utf8++ = (uint8_t) (0x80 | (chr >> 0 & 0x3F)); + } + // TODO: Handle UTF-16 code points that take two entries. + } +} + +// Count how many bytes a utf-16-le encoded string will take in utf-8. +static int _count_utf8_bytes(const uint16_t* buf, size_t len) { + size_t total_bytes = 0; + for (size_t i = 0; i < len; i++) { + uint16_t chr = buf[i]; + if (chr < 0x80) { + total_bytes += 1; + } else if (chr < 0x800) { + total_bytes += 2; + } else { + total_bytes += 3; + } + // TODO: Handle UTF-16 code points that take two entries. + } + return (int) total_bytes; +} + +static void print_utf16(uint16_t* temp_buf, size_t buf_len) { + if ((temp_buf[0] & 0xff) == 0) return; // empty + size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); + size_t utf8_len = (size_t) _count_utf8_bytes(temp_buf + 1, utf16_len); + _convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t*) temp_buf, sizeof(uint16_t) * buf_len); + ((uint8_t*) temp_buf)[utf8_len] = '\0'; + + printf("%s", (char*) temp_buf); +} diff --git a/examples/host/device_info/src/tusb_config.h b/examples/host/device_info/src/tusb_config.h new file mode 100644 index 000000000..484f651b1 --- /dev/null +++ b/examples/host/device_info/src/tusb_config.h @@ -0,0 +1,115 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//-------------------------------------------------------------------- +// Common Configuration +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU +#error CFG_TUSB_MCU must be defined +#endif + +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_NONE +#endif + +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUH_MEM_SECTION +#define CFG_TUH_MEM_SECTION +#endif + +#ifndef CFG_TUH_MEM_ALIGN +#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// Host Configuration +//-------------------------------------------------------------------- + +// Enable Host stack +#define CFG_TUH_ENABLED 1 + +#if CFG_TUSB_MCU == OPT_MCU_RP2040 + #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller + // #define CFG_TUH_MAX3421 1 // use max3421 as host controller + + // host roothub port is 1 if using either pio-usb or max3421 + #if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421) + #define BOARD_TUH_RHPORT 1 + #endif +#endif + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED + +//------------------------- Board Specific -------------------------- + +// RHPort number used for host can be defined by board.mk, default to port 0 +#ifndef BOARD_TUH_RHPORT +#define BOARD_TUH_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUH_MAX_SPEED +#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-------------------------------------------------------------------- +// Driver Configuration +//-------------------------------------------------------------------- + +// Size of buffer to hold descriptors and other data used for enumeration +#define CFG_TUH_ENUMERATION_BUFSIZE 256 + +// only hub class is enabled +#define CFG_TUH_HUB 1 + +// max device support (excluding hub device) +// 1 hub typically has 4 ports +#define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1) + +#ifdef __cplusplus + } +#endif + +#endif -- cgit v1.3.1 From d945261aef7e2c922153e2a85d00791dd1930740 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 18 Jun 2024 12:53:02 +0700 Subject: LOG3 in isr --- examples/host/device_info/src/tusb_config.h | 2 +- src/portable/nordic/nrf5x/dcd_nrf5x.c | 4 ++-- src/portable/nxp/khci/dcd_khci.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/host/device_info/src/tusb_config.h b/examples/host/device_info/src/tusb_config.h index 484f651b1..2e9731eaf 100644 --- a/examples/host/device_info/src/tusb_config.h +++ b/examples/host/device_info/src/tusb_config.h @@ -70,7 +70,7 @@ #define CFG_TUH_ENABLED 1 #if CFG_TUSB_MCU == OPT_MCU_RP2040 - #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller + // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller // #define CFG_TUH_MAX3421 1 // use max3421 as host controller // host roothub port is 1 if using either pio-usb or max3421 diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index abce35245..1cc5c1836 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -907,9 +907,9 @@ void tusb_hal_nrf_power_event(uint32_t event) { USB_EVT_READY = 2 }; -#if CFG_TUSB_DEBUG >= 2 +#if CFG_TUSB_DEBUG >= 3 const char* const power_evt_str[] = {"Detected", "Removed", "Ready"}; - TU_LOG(2, "Power USB event: %s\r\n", power_evt_str[event]); + TU_LOG(3, "Power USB event: %s\r\n", power_evt_str[event]); #endif switch (event) { diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index dc71117b3..ef61146aa 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -540,7 +540,7 @@ void dcd_int_handler(uint8_t rhport) } if (is & USB_ISTAT_SLEEP_MASK) { - // TU_LOG2("Suspend: "); TU_LOG2_HEX(is); + // TU_LOG3("Suspend: "); TU_LOG2_HEX(is); // Note Host usually has extra delay after bus reset (without SOF), which could falsely // detected as Sleep event. Though usbd has debouncing logic so we are good -- cgit v1.3.1 From de62b55042a40a0b1117600d3686787a253c0109 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 18 Jun 2024 13:29:04 +0700 Subject: add dual/host_info_to_device_cdc example --- examples/dual/CMakeLists.txt | 1 + .../dual/host_info_to_device_cdc/CMakeLists.txt | 40 +++ examples/dual/host_info_to_device_cdc/Makefile | 17 ++ examples/dual/host_info_to_device_cdc/only.txt | 6 + examples/dual/host_info_to_device_cdc/src/main.c | 285 +++++++++++++++++++++ .../dual/host_info_to_device_cdc/src/tusb_config.h | 143 +++++++++++ .../host_info_to_device_cdc/src/usb_descriptors.c | 268 +++++++++++++++++++ examples/host/device_info/src/main.c | 3 +- 8 files changed, 761 insertions(+), 2 deletions(-) create mode 100644 examples/dual/host_info_to_device_cdc/CMakeLists.txt create mode 100644 examples/dual/host_info_to_device_cdc/Makefile create mode 100644 examples/dual/host_info_to_device_cdc/only.txt create mode 100644 examples/dual/host_info_to_device_cdc/src/main.c create mode 100644 examples/dual/host_info_to_device_cdc/src/tusb_config.h create mode 100644 examples/dual/host_info_to_device_cdc/src/usb_descriptors.c diff --git a/examples/dual/CMakeLists.txt b/examples/dual/CMakeLists.txt index 15081cf26..f11074e93 100644 --- a/examples/dual/CMakeLists.txt +++ b/examples/dual/CMakeLists.txt @@ -10,4 +10,5 @@ if (FAMILY STREQUAL "rp2040" AND NOT TARGET tinyusb_pico_pio_usb) else () # family_add_subdirectory will filter what to actually add based on selected FAMILY family_add_subdirectory(host_hid_to_device_cdc) + family_add_subdirectory(host_info_to_device_cdc) endif () diff --git a/examples/dual/host_info_to_device_cdc/CMakeLists.txt b/examples/dual/host_info_to_device_cdc/CMakeLists.txt new file mode 100644 index 000000000..a6557c2d0 --- /dev/null +++ b/examples/dual/host_info_to_device_cdc/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.17) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) + +# gets PROJECT name for the example (e.g. -) +family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) + +project(${PROJECT} C CXX ASM) + +# Checks this example is valid for the family and initializes the project +family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) + +add_executable(${PROJECT}) + +# Example source +target_sources(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c + ) + +# Example include +target_include_directories(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src + ) + +# Configure compilation flags and libraries for the example without RTOS. +# See the corresponding function in hw/bsp/FAMILY/family.cmake for details. +family_configure_dual_usb_example(${PROJECT} noos) + +# due to warnings from Pico-PIO-USB +target_compile_options(${PROJECT} PUBLIC + -Wno-error=shadow + -Wno-error=cast-align + -Wno-error=cast-qual + -Wno-error=redundant-decls + -Wno-error=sign-conversion + -Wno-error=conversion + -Wno-error=sign-compare + -Wno-error=unused-function + ) diff --git a/examples/dual/host_info_to_device_cdc/Makefile b/examples/dual/host_info_to_device_cdc/Makefile new file mode 100644 index 000000000..0ede79c17 --- /dev/null +++ b/examples/dual/host_info_to_device_cdc/Makefile @@ -0,0 +1,17 @@ +include ../../build_system/make/make.mk + +INC += \ + src \ + $(TOP)/hw \ + +# Example source +EXAMPLE_SOURCE += $(wildcard src/*.c) +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +CFLAGS += -Wno-error=cast-align -Wno-error=null-dereference + +SRC_C += \ + src/host/hub.c \ + src/host/usbh.c + +include ../../build_system/make/rules.mk diff --git a/examples/dual/host_info_to_device_cdc/only.txt b/examples/dual/host_info_to_device_cdc/only.txt new file mode 100644 index 000000000..cfc87eb4e --- /dev/null +++ b/examples/dual/host_info_to_device_cdc/only.txt @@ -0,0 +1,6 @@ +board:mimxrt1060_evk +board:mimxrt1064_evk +board:mcb1800 +mcu:RP2040 +mcu:ra6m5 +mcu:MAX3421 diff --git a/examples/dual/host_info_to_device_cdc/src/main.c b/examples/dual/host_info_to_device_cdc/src/main.c new file mode 100644 index 000000000..5be531098 --- /dev/null +++ b/examples/dual/host_info_to_device_cdc/src/main.c @@ -0,0 +1,285 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +/* Host example will get device descriptors of attached devices and print it out via device cdc as follows: + * Device 1: ID 046d:c52f + Device Descriptor: + bLength 18 + bDescriptorType 1 + bcdUSB 0200 + bDeviceClass 0 + bDeviceSubClass 0 + bDeviceProtocol 0 + bMaxPacketSize0 8 + idVendor 0x046d + idProduct 0xc52f + bcdDevice 2200 + iManufacturer 1 Logitech + iProduct 2 USB Receiver + iSerialNumber 0 + bNumConfigurations 1 + * + */ + +#include +#include +#include + +#include "bsp/board_api.h" +#include "tusb.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ +// Language ID: English +#define LANGUAGE_ID 0x0409 + +/* Blink pattern + * - 250 ms : device not mounted + * - 1000 ms : device mounted + * - 2500 ms : device is suspended + */ +enum { + BLINK_NOT_MOUNTED = 250, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, +}; + +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; + +static bool is_print[CFG_TUH_DEVICE_MAX+1] = { 0 }; + +static void print_utf16(uint16_t *temp_buf, size_t buf_len); +void led_blinking_task(void); +void cdc_task(void); + +/*------------- MAIN -------------*/ +int main(void) { + board_init(); + + printf("TinyUSB Host Information -> Device CDC Example\r\n"); + + // init device and host stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); + tuh_init(BOARD_TUH_RHPORT); + + if (board_init_after_tusb) { + board_init_after_tusb(); + } + + while (1) { + tud_task(); // tinyusb device task + tuh_task(); // tinyusb host task + cdc_task(); + led_blinking_task(); + } + + return 0; +} + +//--------------------------------------------------------------------+ +// Device CDC +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +void tud_mount_cb(void) { + blink_interval_ms = BLINK_MOUNTED; +} + +// Invoked when device is unmounted +void tud_umount_cb(void) { + blink_interval_ms = BLINK_NOT_MOUNTED; +} + +// Invoked when usb bus is suspended +// remote_wakeup_en : if host allow us to perform remote wakeup +// Within 7ms, device must draw an average of current less than 2.5 mA from bus +void tud_suspend_cb(bool remote_wakeup_en) { + (void) remote_wakeup_en; + blink_interval_ms = BLINK_SUSPENDED; +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) { + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; +} + +#if 1 +#define cdc_printf(...) \ + do { \ + char _tempbuf[256]; \ + int count = sprintf(_tempbuf, __VA_ARGS__); \ + tud_cdc_write(_tempbuf, (uint32_t) count); \ + tud_cdc_write_flush(); \ + tud_task(); \ + } while(0) +#endif + +//#define cdc_printf printf + +void print_device_info(uint8_t daddr) { + tusb_desc_device_t desc_device; + uint8_t xfer_result = tuh_descriptor_get_device_sync(daddr, &desc_device, 18); + if (XFER_RESULT_SUCCESS != xfer_result) { + tud_cdc_write_str("Failed to get device descriptor\r\n"); + return; + } + + cdc_printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct); + cdc_printf("Device Descriptor:\r\n"); + cdc_printf(" bLength %u\r\n" , desc_device.bLength); + cdc_printf(" bDescriptorType %u\r\n" , desc_device.bDescriptorType); + cdc_printf(" bcdUSB %04x\r\n" , desc_device.bcdUSB); + cdc_printf(" bDeviceClass %u\r\n" , desc_device.bDeviceClass); + cdc_printf(" bDeviceSubClass %u\r\n" , desc_device.bDeviceSubClass); + cdc_printf(" bDeviceProtocol %u\r\n" , desc_device.bDeviceProtocol); + cdc_printf(" bMaxPacketSize0 %u\r\n" , desc_device.bMaxPacketSize0); + cdc_printf(" idVendor 0x%04x\r\n" , desc_device.idVendor); + cdc_printf(" idProduct 0x%04x\r\n" , desc_device.idProduct); + cdc_printf(" bcdDevice %04x\r\n" , desc_device.bcdDevice); + + // Get String descriptor using Sync API + uint16_t buf[128]; + + cdc_printf(" iManufacturer %u " , desc_device.iManufacturer); + xfer_result = tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf)); + if (XFER_RESULT_SUCCESS == xfer_result ) { + print_utf16(buf, TU_ARRAY_SIZE(buf)); + } + tud_cdc_write_str("\r\n"); + + cdc_printf(" iProduct %u " , desc_device.iProduct); + xfer_result = tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf)); + if (XFER_RESULT_SUCCESS == xfer_result) { + print_utf16(buf, TU_ARRAY_SIZE(buf)); + } + tud_cdc_write_str("\r\n"); + + cdc_printf(" iSerialNumber %u " , desc_device.iSerialNumber); + xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf)); + if (XFER_RESULT_SUCCESS == xfer_result) { + print_utf16(buf, TU_ARRAY_SIZE(buf)); + } + tud_cdc_write_str("\r\n"); + + cdc_printf(" bNumConfigurations %u\r\n" , desc_device.bNumConfigurations); +} + +void cdc_task(void) { + if (tud_cdc_connected()) { + for (uint8_t daddr = 1; daddr <= CFG_TUH_DEVICE_MAX; daddr++) { + if (tuh_mounted(daddr)) { + if (is_print[daddr]) { + is_print[daddr] = false; + print_device_info(daddr); + tud_cdc_write_flush(); + } + } + } + } +} + +//--------------------------------------------------------------------+ +// Host Get device information +//--------------------------------------------------------------------+ +void tuh_mount_cb(uint8_t daddr) { + printf("mounted device %u\r\n", daddr); + is_print[daddr] = true; +} + +void tuh_umount_cb(uint8_t daddr) { + printf("unmounted device %u\r\n", daddr); + is_print[daddr] = false; +} + +//--------------------------------------------------------------------+ +// Blinking Task +//--------------------------------------------------------------------+ +void led_blinking_task(void) { + static uint32_t start_ms = 0; + static bool led_state = false; + + // Blink every interval ms + if (board_millis() - start_ms < blink_interval_ms) return; // not enough time + start_ms += blink_interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle +} + +//--------------------------------------------------------------------+ +// String Descriptor Helper +//--------------------------------------------------------------------+ + +static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, uint8_t *utf8, size_t utf8_len) { + // TODO: Check for runover. + (void)utf8_len; + // Get the UTF-16 length out of the data itself. + + for (size_t i = 0; i < utf16_len; i++) { + uint16_t chr = utf16[i]; + if (chr < 0x80) { + *utf8++ = chr & 0xffu; + } else if (chr < 0x800) { + *utf8++ = (uint8_t)(0xC0 | (chr >> 6 & 0x1F)); + *utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F)); + } else { + // TODO: Verify surrogate. + *utf8++ = (uint8_t)(0xE0 | (chr >> 12 & 0x0F)); + *utf8++ = (uint8_t)(0x80 | (chr >> 6 & 0x3F)); + *utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F)); + } + // TODO: Handle UTF-16 code points that take two entries. + } +} + +// Count how many bytes a utf-16-le encoded string will take in utf-8. +static int _count_utf8_bytes(const uint16_t *buf, size_t len) { + size_t total_bytes = 0; + for (size_t i = 0; i < len; i++) { + uint16_t chr = buf[i]; + if (chr < 0x80) { + total_bytes += 1; + } else if (chr < 0x800) { + total_bytes += 2; + } else { + total_bytes += 3; + } + // TODO: Handle UTF-16 code points that take two entries. + } + return (int) total_bytes; +} + +static void print_utf16(uint16_t *temp_buf, size_t buf_len) { + if ((temp_buf[0] & 0xff) == 0) return; // empty + size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); + size_t utf8_len = (size_t) _count_utf8_bytes(temp_buf + 1, utf16_len); + _convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, sizeof(uint16_t) * buf_len); + ((uint8_t*) temp_buf)[utf8_len] = '\0'; + + tud_cdc_write(temp_buf, utf8_len); + tud_cdc_write_flush(); + tud_task(); +} diff --git a/examples/dual/host_info_to_device_cdc/src/tusb_config.h b/examples/dual/host_info_to_device_cdc/src/tusb_config.h new file mode 100644 index 000000000..bb47fbf4a --- /dev/null +++ b/examples/dual/host_info_to_device_cdc/src/tusb_config.h @@ -0,0 +1,143 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Board Specific Configuration +//--------------------------------------------------------------------+ + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_TUD_RHPORT +#define BOARD_TUD_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUD_MAX_SPEED +#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +// RHPort number used for host can be defined by board.mk, default to port 1 +#ifndef BOARD_TUH_RHPORT +#define BOARD_TUH_RHPORT 1 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUH_MAX_SPEED +#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU +#error CFG_TUSB_MCU must be defined +#endif + +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_NONE +#endif + +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +// Enable Device stack, Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUD_ENABLED 1 +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED + +// Enable Host stack, Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUH_ENABLED 1 +#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED + +#if CFG_TUSB_MCU == OPT_MCU_RP2040 +// Use pico-pio-usb as host controller for raspberry rp2040 +#define CFG_TUH_RPI_PIO_USB 1 +#endif + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUD_MEM_SECTION +#define CFG_TUD_MEM_SECTION +#endif + +#ifndef CFG_TUD_MEM_ALIGN +#define CFG_TUD_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//------------- CLASS -------------// +#define CFG_TUD_CDC 1 + +// CDC FIFO size of TX and RX +#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + +// CDC Endpoint transfer buffer size, more is faster +#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + +//-------------------------------------------------------------------- +// HOST CONFIGURATION +//-------------------------------------------------------------------- + +// Size of buffer to hold descriptors and other data used for enumeration +#define CFG_TUH_ENUMERATION_BUFSIZE 256 + +#ifndef CFG_TUH_MEM_SECTION +#define CFG_TUH_MEM_SECTION +#endif + +#ifndef CFG_TUH_MEM_ALIGN +#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +#define CFG_TUH_HUB 1 +// max device support (excluding hub device) +#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/examples/dual/host_info_to_device_cdc/src/usb_descriptors.c b/examples/dual/host_info_to_device_cdc/src/usb_descriptors.c new file mode 100644 index 000000000..9d57737fb --- /dev/null +++ b/examples/dual/host_info_to_device_cdc/src/usb_descriptors.c @@ -0,0 +1,268 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "bsp/board_api.h" +#include "tusb.h" + +/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. + * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. + * + * Auto ProductID layout's Bitmap: + * [MSB] HID | MSC | CDC [LSB] + */ +#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ + _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) + +#define USB_VID 0xCafe +#define USB_BCD 0x0200 + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +tusb_desc_device_t const desc_device = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = USB_BCD, + + // Use Interface Association Descriptor (IAD) for CDC + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = USB_VID, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const* tud_descriptor_device_cb(void) { + return (uint8_t const*) &desc_device; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ + +enum { + ITF_NUM_CDC = 0, + ITF_NUM_CDC_DATA, + ITF_NUM_TOTAL +}; + +#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX + // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number + // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ... + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x82 + +#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X + // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x83 + +#elif CFG_TUSB_MCU == OPT_MCU_CXD56 + // CXD56 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number + // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) + #define EPNUM_CDC_NOTIF 0x83 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x81 + +#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X +// FT9XX doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x83 + +#else + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x82 + +#endif + +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN) + +// full speed configuration +uint8_t const desc_fs_configuration[] = { + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + + // Interface number, string index, EP notification address and size, EP data address (out, in) and size. + TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), +}; + +#if TUD_OPT_HIGH_SPEED +// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration + +// high speed configuration +uint8_t const desc_hs_configuration[] = { + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + + // Interface number, string index, EP notification address and size, EP data address (out, in) and size. + TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512), +}; + +// other speed configuration +uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; + +// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed +tusb_desc_device_qualifier_t const desc_device_qualifier = { + .bLength = sizeof(tusb_desc_device_qualifier_t), + .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, + .bcdUSB = USB_BCD, + + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .bNumConfigurations = 0x01, + .bReserved = 0x00 +}; + +// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. +// device_qualifier descriptor describes information about a high-speed capable device that would +// change if the device were operating at the other speed. If not highspeed capable stall this request. +uint8_t const* tud_descriptor_device_qualifier_cb(void) { + return (uint8_t const*) &desc_device_qualifier; +} + +// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa +uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) { + (void) index; // for multiple configurations + + // if link speed is high return fullspeed config, and vice versa + // Note: the descriptor type is OHER_SPEED_CONFIG instead of CONFIG + memcpy(desc_other_speed_config, + (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, + CONFIG_TOTAL_LEN); + + desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; + + return desc_other_speed_config; +} + +#endif // highspeed + + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { + (void) index; // for multiple configurations + +#if TUD_OPT_HIGH_SPEED + // Although we are highspeed, host may be fullspeed. + return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; +#else + return desc_fs_configuration; +#endif +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +// String Descriptor Index +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, +}; + +// array of pointer to string descriptors +char const* string_desc_arr[] = { + (const char[]) {0x09, 0x04}, // 0: is supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + NULL, // 3: Serials will use unique ID if possible + "TinyUSB CDC", // 4: CDC Interface +}; + +static uint16_t _desc_str[32 + 1]; + +// Invoked when received GET STRING DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { + (void) langid; + size_t chr_count; + + switch (index) { + case STRID_LANGID: + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + break; + + case STRID_SERIAL: + chr_count = board_usb_get_serial(_desc_str + 1, 32); + break; + + default: + // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. + // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors + + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) return NULL; + + const char* str = string_desc_arr[index]; + + // Cap at max char + chr_count = strlen(str); + size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type + if (chr_count > max_count) chr_count = max_count; + + // Convert ASCII string into UTF-16 + for (size_t i = 0; i < chr_count; i++) { + _desc_str[1 + i] = str[i]; + } + break; + } + + // first byte is length (including header), second byte is string type + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); + + return _desc_str; +} diff --git a/examples/host/device_info/src/main.c b/examples/host/device_info/src/main.c index 60d7e9c80..18beea663 100644 --- a/examples/host/device_info/src/main.c +++ b/examples/host/device_info/src/main.c @@ -23,8 +23,7 @@ * */ -/* Host example will get device descriptors of attached devices and print it out via - * device cdc (Serial) as follows: +/* Host example will get device descriptors of attached devices and print it out via uart/rtt (logger) as follows: * Device 1: ID 046d:c52f Device Descriptor: bLength 18 -- cgit v1.3.1 From 5083d1eb3399d605d64b3e30a784731f330e7774 Mon Sep 17 00:00:00 2001 From: Okarss <104319900+Okarss@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:12:44 +0300 Subject: Update Host mode information for FSDEV devices --- docs/reference/supported.rst | 13 +++++++------ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 6 +++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index d0e0bf1af..441c885ac 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -104,11 +104,11 @@ Supported MCUs | +-----------------------+--------+------+-----------+-------------------+--------------+ | | F7 | ✔ | | ✔ | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | G0 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | G0 | ✔ | | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ | | G4 | ✔ | ✖ | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | H5 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | H5 | ✔ | | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ | | H7 | ✔ | | ✔ | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ @@ -124,13 +124,13 @@ Supported MCUs | +-----------------------+--------+------+-----------+-------------------+--------------+ | | L5 | ✔ | ✖ | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | U5 | 535, 545 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | U5 | 535, 545 | ✔ | | ✖ | stm32_fsdev | | | | +------------------+--------+------+-----------+-------------------+--------------+ | | | 575, 585 | ✔ | | ✖ | dwc2 | | | | +------------------+--------+------+-----------+-------------------+--------------+ | | | 59x,5Ax,5Fx,5Gx | ✔ | | ✔ | dwc2 | | | +----+------------------+--------+------+-----------+-------------------+--------------+ -| | WBx5 | ✔ | | | stm32_fsdev | | +| | WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | | +-----------------------+--------+------+-----------+-------------------+--------------+ @@ -153,8 +153,9 @@ Table Legend = =================== ✔ Supported -⚠ WIP/partial support -✖ Not supported +⚠ Partial support +✖ Not supported by hardware +[empty] Unknown = =================== Supported Boards diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 0ecb6ea05..fb499fa18 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -41,15 +41,15 @@ * F102, F103 512 byte buffer; no internal D+ pull-up (maybe many more changes?) * F302xB/C, F303xB/C, F373 512 byte buffer; no internal D+ pull-up * F302x6/8, F302xD/E2, F303xD/E 1024 byte buffer; no internal D+ pull-up - * G0 2048 byte buffer; 32-bit bus + * G0 2048 byte buffer; 32-bit bus; host mode * G4 1024 byte buffer - * H5 2048 byte buffer; 32-bit bus + * H5 2048 byte buffer; 32-bit bus; host mode * L0x2, L0x3 1024 byte buffer * L1 512 byte buffer * L4x2, L4x3 1024 byte buffer * L5 1024 byte buffer * U0 1024 byte buffer; 32-bit bus - * U535, U545 2048 byte buffer; 32-bit bus + * U535, U545 2048 byte buffer; 32-bit bus; host mode * WB35, WB55 1024 byte buffer * * To use this driver, you must: -- cgit v1.3.1 From ac3ec598458c63d9866019dd6c42ef0d304b8bf4 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 18 Jun 2024 16:18:58 +0700 Subject: add optional COMPILE_DEFINE from cmake cli --- hw/bsp/family_support.cmake | 30 ++++++++++++++---------------- hw/bsp/rp2040/family.cmake | 6 ++++++ 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 94d55f04a..d631c8563 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -140,7 +140,6 @@ function(family_filter RESULT DIR) endif() endfunction() - function(family_add_subdirectory DIR) family_filter(SHOULD_ADD "${DIR}") if (SHOULD_ADD) @@ -148,13 +147,11 @@ function(family_add_subdirectory DIR) endif() endfunction() - function(family_get_project_name OUTPUT_NAME DIR) get_filename_component(SHORT_NAME ${DIR} NAME) set(${OUTPUT_NAME} ${TINYUSB_FAMILY_PROJECT_NAME_PREFIX}${SHORT_NAME} PARENT_SCOPE) endfunction() - function(family_initialize_project PROJECT DIR) # set output suffix to .elf (skip espressif and rp2040) if(NOT FAMILY STREQUAL "espressif" AND NOT FAMILY STREQUAL "rp2040") @@ -168,7 +165,6 @@ function(family_initialize_project PROJECT DIR) endif() endfunction() - #------------------------------------------------------------- # Common Target Configure # Most families use these settings except rp2040 and espressif @@ -194,7 +190,6 @@ function(family_add_rtos TARGET RTOS) endif () endfunction() - # Add common configuration to example function(family_configure_common TARGET RTOS) family_add_rtos(${TARGET} ${RTOS}) @@ -205,14 +200,12 @@ function(family_configure_common TARGET RTOS) BOARD_${BOARD_UPPER} ) - # run size after build - find_program(SIZE_EXE ${CMAKE_SIZE}) - if(NOT ${SIZE_EXE} STREQUAL SIZE_EXE-NOTFOUND) - add_custom_command(TARGET ${TARGET} POST_BUILD - COMMAND ${SIZE_EXE} $ - ) - endif () - # Add warnings flags + # compile define from command line + if(DEFINED COMPILE_DEFINE) + #separate_arguments(COMPILE_DEFINE_LIST UNIX_COMMAND "${COMPILE_DEFINE}") + target_compile_definitions(${TARGET} PUBLIC ${COMPILE_DEFINE}) + endif() + target_compile_options(${TARGET} PUBLIC ${WARNING_FLAGS_${CMAKE_C_COMPILER_ID}}) # Generate linker map file @@ -235,7 +228,6 @@ function(family_configure_common TARGET RTOS) # LOGGER option if (DEFINED LOGGER) target_compile_definitions(${TARGET} PUBLIC LOGGER_${LOGGER}) - # Add segger rtt to example if(LOGGER STREQUAL "RTT" OR LOGGER STREQUAL "rtt") if (NOT TARGET segger_rtt) @@ -246,8 +238,15 @@ function(family_configure_common TARGET RTOS) target_link_libraries(${TARGET} PUBLIC segger_rtt) endif () endif () -endfunction() + # run size after build + find_program(SIZE_EXE ${CMAKE_SIZE}) + if(NOT ${SIZE_EXE} STREQUAL SIZE_EXE-NOTFOUND) + add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND ${SIZE_EXE} $ + ) + endif () +endfunction() # Add tinyusb to example function(family_add_tinyusb TARGET OPT_MCU RTOS) @@ -289,7 +288,6 @@ function(family_add_tinyusb TARGET OPT_MCU RTOS) endfunction() - # Add bin/hex output function(family_add_bin_hex TARGET) add_custom_command(TARGET ${TARGET} POST_BUILD diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index b41d7fbea..5d82cbf62 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -175,6 +175,12 @@ function(family_configure_target TARGET RTOS) # export RTOS_SUFFIX to parent scope set(RTOS_SUFFIX ${RTOS_SUFFIX} PARENT_SCOPE) + # compile define from command line + if(DEFINED COMPILE_DEFINE) + #separate_arguments(COMPILE_DEFINE_LIST UNIX_COMMAND "${COMPILE_DEFINE}") + target_compile_definitions(${TARGET} PUBLIC ${COMPILE_DEFINE}) + endif() + pico_add_extra_outputs(${TARGET}) pico_enable_stdio_uart(${TARGET} 1) target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_board${RTOS_SUFFIX} tinyusb_additions) -- cgit v1.3.1 From 458be5dad8cad2819943a006c781a6bc508ea048 Mon Sep 17 00:00:00 2001 From: Okarss <104319900+Okarss@users.noreply.github.com> Date: Tue, 18 Jun 2024 13:40:49 +0300 Subject: Fix the table --- docs/reference/supported.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 441c885ac..8b1d99b41 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -123,7 +123,7 @@ Supported MCUs | | L4+ | ✔ | | | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ | | L5 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ +| +----+------------------+--------+------+-----------+-------------------+--------------+ | | U5 | 535, 545 | ✔ | | ✖ | stm32_fsdev | | | | +------------------+--------+------+-----------+-------------------+--------------+ | | | 575, 585 | ✔ | | ✖ | dwc2 | | -- cgit v1.3.1 From 5e58ec127ff30ce48a9fcb819acfc05edc92f332 Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Thu, 20 Jun 2024 09:33:01 +0930 Subject: usbh: Add set address recovery time Ref USB Spec 9.2.6.3 --- src/host/usbh.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/host/usbh.c b/src/host/usbh.c index a94c22c4c..8c488aaa2 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1421,6 +1421,9 @@ static void process_enumeration(tuh_xfer_t* xfer) { break; case ENUM_GET_DEVICE_DESC: { + // Allow 2ms for address recovery time, Ref USB Spec 9.2.6.3 + osal_task_delay(2); + uint8_t const new_addr = (uint8_t) tu_le16toh(xfer->setup->wValue); usbh_device_t* new_dev = get_device(new_addr); -- cgit v1.3.1 From 0d79da37e79b8abd04f7f9ba9c15114d84e9810a Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Thu, 20 Jun 2024 15:15:51 +1000 Subject: synopsys/dwc2_esp32: Add header for vTaskDelay. --- src/portable/synopsys/dwc2/dwc2_esp32.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index c50dd66b8..932f52f40 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -35,6 +35,7 @@ #include "esp_intr_alloc.h" #include "soc/periph_defs.h" //#include "soc/usb_periph.h" +#include "freertos/task.h" #define DWC2_REG_BASE 0x60080000UL #define DWC2_EP_MAX 6 // USB_OUT_EP_NUM. TODO ESP32Sx only has 5 tx fifo (5 endpoint IN) -- cgit v1.3.1 From 02bea8982e36b6a60fd424e1040c7e37c95e0628 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 21 Jun 2024 16:08:37 +0700 Subject: add new ch32v203g6u board, sysfreq is defined in board.cmake/mk --- hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk | 4 +- hw/bsp/ch32v10x/family.cmake | 4 +- hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.cmake | 12 ------ hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h | 16 -------- hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.mk | 7 ---- .../ch32v20x/boards/ch32v203c_r0_1v0/board.cmake | 13 +++++++ hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.h | 21 ++++++++++ hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.mk | 9 +++++ .../ch32v20x/boards/ch32v203g_r0_1v0/board.cmake | 11 ++++++ hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.h | 21 ++++++++++ hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.mk | 9 +++++ hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake | 1 + hw/bsp/ch32v20x/boards/nanoch32v203/board.h | 6 ++- hw/bsp/ch32v20x/boards/nanoch32v203/board.mk | 8 ++-- hw/bsp/ch32v20x/family.c | 45 ++++++++++++---------- hw/bsp/ch32v20x/family.cmake | 9 +++-- hw/bsp/ch32v20x/linker/ch32v20x.ld | 11 +++--- hw/bsp/ch32v20x/system_ch32v20x.c | 2 +- 18 files changed, 135 insertions(+), 74 deletions(-) delete mode 100644 hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.cmake delete mode 100644 hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h delete mode 100644 hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.mk create mode 100644 hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake create mode 100644 hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.h create mode 100644 hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.mk create mode 100644 hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake create mode 100644 hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.h create mode 100644 hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.mk diff --git a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk index 70e65333c..e594f42a7 100644 --- a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk +++ b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk @@ -1,5 +1,5 @@ CFLAGS += -DCFG_EXAMPLE_MSC_DUAL_READONLY LDFLAGS += \ - -Wl,--defsym=__flash_size=64K \ - -Wl,--defsym=__ram_size=20K \ + -Wl,--defsym=__FLASH_SIZE=64K \ + -Wl,--defsym=__RAM_SIZE=20K \ diff --git a/hw/bsp/ch32v10x/family.cmake b/hw/bsp/ch32v10x/family.cmake index b0d8241d3..c0af0ef44 100644 --- a/hw/bsp/ch32v10x/family.cmake +++ b/hw/bsp/ch32v10x/family.cmake @@ -59,8 +59,8 @@ function(add_board_target BOARD_TARGET) ) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" - -Wl,--defsym=__flash_size=${LD_FLASH_SIZE} - -Wl,--defsym=__ram_size=${LD_RAM_SIZE} + -Wl,--defsym=__FLASH_SIZE=${LD_FLASH_SIZE} + -Wl,--defsym=__RAM_SIZE=${LD_RAM_SIZE} -nostartfiles --specs=nosys.specs --specs=nano.specs ) diff --git a/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.cmake b/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.cmake deleted file mode 100644 index 31b6b716e..000000000 --- a/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.cmake +++ /dev/null @@ -1,12 +0,0 @@ -set(MCU_VARIANT D6) - -set(LD_FLASH_SIZE 64K) -set(LD_RAM_SIZE 20K) - -# set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${CH32_FAMILY}_tinyuf2.ld) - -function(update_board TARGET) - target_compile_definitions(${TARGET} PUBLIC - CFG_EXAMPLE_MSC_DUAL_READONLY - ) -endfunction() diff --git a/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h b/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h deleted file mode 100644 index 3ed2aef04..000000000 --- a/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define LED_PORT GPIOA -#define LED_PIN GPIO_Pin_15 -#define LED_STATE_ON 0 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.mk b/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.mk deleted file mode 100644 index 7d7462312..000000000 --- a/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.mk +++ /dev/null @@ -1,7 +0,0 @@ -MCU_VARIANT = D6 - -CFLAGS += -DCFG_EXAMPLE_MSC_DUAL_READONLY - -LDFLAGS += \ - -Wl,--defsym=__flash_size=64K \ - -Wl,--defsym=__ram_size=20K \ diff --git a/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake new file mode 100644 index 000000000..3dd87d3de --- /dev/null +++ b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake @@ -0,0 +1,13 @@ +set(MCU_VARIANT D6) + +set(LD_FLASH_SIZE 64K) +set(LD_RAM_SIZE 20K) + +# set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${CH32_FAMILY}_tinyuf2.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + SYSCLK_FREQ_144MHz_HSE=144000000 + CFG_EXAMPLE_MSC_DUAL_READONLY + ) +endfunction() diff --git a/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.h b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.h new file mode 100644 index 000000000..64eaf931e --- /dev/null +++ b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.h @@ -0,0 +1,21 @@ +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define LED_PORT GPIOA +#define LED_PIN GPIO_Pin_15 +#define LED_STATE_ON 0 + +#define UART_DEV USART1 +#define UART_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE) +#define UART_TX_PIN GPIO_Pin_9 +#define UART_RX_PIN GPIO_Pin_10 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.mk b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.mk new file mode 100644 index 000000000..7d5894629 --- /dev/null +++ b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.mk @@ -0,0 +1,9 @@ +MCU_VARIANT = D6 + +CFLAGS += \ + -DSYSCLK_FREQ_144MHz_HSE=144000000 \ + -DCFG_EXAMPLE_MSC_DUAL_READONLY \ + +LDFLAGS += \ + -Wl,--defsym=__FLASH_SIZE=64K \ + -Wl,--defsym=__RAM_SIZE=20K \ diff --git a/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake new file mode 100644 index 000000000..6e5305212 --- /dev/null +++ b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake @@ -0,0 +1,11 @@ +set(MCU_VARIANT D6) + +set(LD_FLASH_SIZE 32K) +set(LD_RAM_SIZE 10K) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + SYSCLK_FREQ_144MHz_HSI=144000000 + CFG_EXAMPLE_MSC_DUAL_READONLY + ) +endfunction() diff --git a/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.h b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.h new file mode 100644 index 000000000..d6c3a64c8 --- /dev/null +++ b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.h @@ -0,0 +1,21 @@ +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define LED_PORT GPIOA +#define LED_PIN GPIO_Pin_0 +#define LED_STATE_ON 1 + +#define UART_DEV USART2 +#define UART_CLOCK_EN() RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE) +#define UART_TX_PIN GPIO_Pin_2 +#define UART_RX_PIN GPIO_Pin_3 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.mk b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.mk new file mode 100644 index 000000000..e5e4d63ba --- /dev/null +++ b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.mk @@ -0,0 +1,9 @@ +MCU_VARIANT = D6 + +CFLAGS += \ + -DSYSCLK_FREQ_144MHz_HSI=144000000 \ + -DCFG_EXAMPLE_MSC_DUAL_READONLY \ + +LDFLAGS += \ + -Wl,--defsym=__FLASH_SIZE=32K \ + -Wl,--defsym=__RAM_SIZE=10K \ diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake index 8d3e0326e..f8dc862a7 100644 --- a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake @@ -5,6 +5,7 @@ set(LD_RAM_SIZE 20K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC + SYSCLK_FREQ_144MHz_HSE=144000000 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.h b/hw/bsp/ch32v20x/boards/nanoch32v203/board.h index c8d28d90f..64eaf931e 100644 --- a/hw/bsp/ch32v20x/boards/nanoch32v203/board.h +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.h @@ -8,7 +8,11 @@ extern "C" { #define LED_PORT GPIOA #define LED_PIN GPIO_Pin_15 #define LED_STATE_ON 0 -#define LED_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE) + +#define UART_DEV USART1 +#define UART_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE) +#define UART_TX_PIN GPIO_Pin_9 +#define UART_RX_PIN GPIO_Pin_10 #ifdef __cplusplus } diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk b/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk index 7d7462312..7d5894629 100644 --- a/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk @@ -1,7 +1,9 @@ MCU_VARIANT = D6 -CFLAGS += -DCFG_EXAMPLE_MSC_DUAL_READONLY +CFLAGS += \ + -DSYSCLK_FREQ_144MHz_HSE=144000000 \ + -DCFG_EXAMPLE_MSC_DUAL_READONLY \ LDFLAGS += \ - -Wl,--defsym=__flash_size=64K \ - -Wl,--defsym=__ram_size=20K \ + -Wl,--defsym=__FLASH_SIZE=64K \ + -Wl,--defsym=__RAM_SIZE=20K \ diff --git a/hw/bsp/ch32v20x/family.c b/hw/bsp/ch32v20x/family.c index 8575f5699..ea98a5e19 100644 --- a/hw/bsp/ch32v20x/family.c +++ b/hw/bsp/ch32v20x/family.c @@ -96,28 +96,17 @@ void board_init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); - uint8_t usb_div; - switch (SystemCoreClock) { - case 48000000: usb_div = RCC_USBCLKSource_PLLCLK_Div1; break; - case 96000000: usb_div = RCC_USBCLKSource_PLLCLK_Div2; break; - case 144000000: usb_div = RCC_USBCLKSource_PLLCLK_Div3; break; - default: TU_ASSERT(0,); break; - } - RCC_USBCLKConfig(usb_div); - RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); // FSDEV - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); // USB FS - GPIO_InitTypeDef GPIO_InitStructure = { .GPIO_Pin = LED_PIN, .GPIO_Mode = GPIO_Mode_Out_OD, - .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Speed = GPIO_Speed_10MHz, }; GPIO_Init(LED_PORT, &GPIO_InitStructure); - // UART TX is PA9 - RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); +#ifdef UART_DEV + UART_CLOCK_EN(); GPIO_InitTypeDef usart_init = { - .GPIO_Pin = GPIO_Pin_9, + .GPIO_Pin = UART_TX_PIN, .GPIO_Speed = GPIO_Speed_50MHz, .GPIO_Mode = GPIO_Mode_AF_PP, }; @@ -131,11 +120,23 @@ void board_init(void) { .USART_Mode = USART_Mode_Tx, .USART_HardwareFlowControl = USART_HardwareFlowControl_None, }; - USART_Init(USART1, &usart); - USART_Cmd(USART1, ENABLE); + USART_Init(UART_DEV, &usart); + USART_Cmd(UART_DEV, ENABLE); +#endif + + // USB init + uint8_t usb_div; + switch (SystemCoreClock) { + case 48000000: usb_div = RCC_USBCLKSource_PLLCLK_Div1; break; + case 96000000: usb_div = RCC_USBCLKSource_PLLCLK_Div2; break; + case 144000000: usb_div = RCC_USBCLKSource_PLLCLK_Div3; break; + default: TU_ASSERT(0,); break; + } + RCC_USBCLKConfig(usb_div); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); // FSDEV + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); // USB FS __enable_irq(); - board_delay(2); } void board_led_write(bool state) { @@ -153,11 +154,15 @@ int board_uart_read(uint8_t *buf, int len) { } int board_uart_write(void const *buf, int len) { +#ifdef UART_DEV const char *bufc = (const char *) buf; for (int i = 0; i < len; i++) { - while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); - USART_SendData(USART1, *bufc++); + while (USART_GetFlagStatus(UART_DEV, USART_FLAG_TC) == RESET); + USART_SendData(UART_DEV, *bufc++); } +#else + (void) buf; (void) len; +#endif return len; } diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake index 28fd13697..faa79ed66 100644 --- a/hw/bsp/ch32v20x/family.cmake +++ b/hw/bsp/ch32v20x/family.cmake @@ -41,6 +41,7 @@ function(add_board_target BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_SRC_DIR}/Core/core_riscv.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_flash.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c @@ -76,14 +77,14 @@ function(add_board_target BOARD_TARGET) -mcmodel=medany ) target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -Wl,--defsym=__flash_size=${LD_FLASH_SIZE} - -Wl,--defsym=__ram_size=${LD_RAM_SIZE} -nostartfiles --specs=nosys.specs --specs=nano.specs + -Wl,--defsym=__FLASH_SIZE=${LD_FLASH_SIZE} + -Wl,--defsym=__RAM_SIZE=${LD_RAM_SIZE} + "LINKER:--script=${LD_FILE_GNU}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - message(FATAL_ERROR "Clang is not supported for MSP432E4") + message(FATAL_ERROR "Clang is not supported for CH32v") elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" diff --git a/hw/bsp/ch32v20x/linker/ch32v20x.ld b/hw/bsp/ch32v20x/linker/ch32v20x.ld index cd5c8dc17..f84808b0d 100644 --- a/hw/bsp/ch32v20x/linker/ch32v20x.ld +++ b/hw/bsp/ch32v20x/linker/ch32v20x.ld @@ -1,17 +1,16 @@ /* Define default values if not already defined */ -__FLASH_SIZE = DEFINED(__flash_size) ? __flash_size : 64K; -__RAM_SIZE = DEFINED(__ram_size) ? __ram_size : 20K; +__flash_size = DEFINED(__FLASH_SIZE) ? __FLASH_SIZE : 64K; +__ram_size = DEFINED(__RAM_SIZE) ? __RAM_SIZE : 20K; +__stack_size = DEFINED(__STACK_SIZE) ? __STACK_SIZE : 2048; MEMORY { - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __FLASH_SIZE - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __RAM_SIZE + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __flash_size + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __ram_size } ENTRY( _start ) -__stack_size = 2048; - PROVIDE( _stack_size = __stack_size ); SECTIONS diff --git a/hw/bsp/ch32v20x/system_ch32v20x.c b/hw/bsp/ch32v20x/system_ch32v20x.c index bdc0d498f..435feae1b 100644 --- a/hw/bsp/ch32v20x/system_ch32v20x.c +++ b/hw/bsp/ch32v20x/system_ch32v20x.c @@ -24,7 +24,7 @@ //#define SYSCLK_FREQ_72MHz_HSE 72000000 // #define SYSCLK_FREQ_96MHz_HSE 96000000 //#define SYSCLK_FREQ_120MHz_HSE 120000000 -#define SYSCLK_FREQ_144MHz_HSE 144000000 +//#define SYSCLK_FREQ_144MHz_HSE 144000000 //#define SYSCLK_FREQ_HSI HSI_VALUE //#define SYSCLK_FREQ_48MHz_HSI 48000000 //#define SYSCLK_FREQ_56MHz_HSI 56000000 -- cgit v1.3.1 From ab55bc077d02f031ac08a60465a62fc3b59adb12 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 21 Jun 2024 16:09:08 +0700 Subject: update cmake.xml --- .idea/cmake.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 5568609dd..dd0efb857 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -3,6 +3,7 @@ + @@ -131,8 +132,9 @@ - - + + + -- cgit v1.3.1 From f9cd5ccdf0a24b66f6d5b7aeb760e757723eb18e Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 21 Jun 2024 18:50:44 +0700 Subject: skip examples for ch32v203g6 --- .idea/cmake.xml | 2 +- examples/device/cdc_msc/skip.txt | 1 + examples/device/dynamic_configuration/skip.txt | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index dd0efb857..3c51031c1 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -134,7 +134,7 @@ - + diff --git a/examples/device/cdc_msc/skip.txt b/examples/device/cdc_msc/skip.txt index 833fd072c..b6252e405 100644 --- a/examples/device/cdc_msc/skip.txt +++ b/examples/device/cdc_msc/skip.txt @@ -1,2 +1,3 @@ mcu:SAMD11 family:espressif +board:ch32v203g_r0_1v0 diff --git a/examples/device/dynamic_configuration/skip.txt b/examples/device/dynamic_configuration/skip.txt index 833fd072c..b6252e405 100644 --- a/examples/device/dynamic_configuration/skip.txt +++ b/examples/device/dynamic_configuration/skip.txt @@ -1,2 +1,3 @@ mcu:SAMD11 family:espressif +board:ch32v203g_r0_1v0 -- cgit v1.3.1 From 7594d8e103b4df116c2f9fb038c414d729896518 Mon Sep 17 00:00:00 2001 From: Okarss <104319900+Okarss@users.noreply.github.com> Date: Fri, 21 Jun 2024 15:56:54 +0300 Subject: Fix the legend --- docs/reference/supported.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 8b1d99b41..5a66b7428 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -151,12 +151,12 @@ Supported MCUs Table Legend ------------ -= =================== -✔ Supported -⚠ Partial support -✖ Not supported by hardware -[empty] Unknown -= =================== +========= ========================= +✔ Supported +⚠ Partial support +✖ Not supported by hardware +\[empty\] Unknown +========= ========================= Supported Boards ================ -- cgit v1.3.1 From 822ff7b316facf0bf0856dd4aa8418bd6aef18ea Mon Sep 17 00:00:00 2001 From: Okarss <104319900+Okarss@users.noreply.github.com> Date: Fri, 21 Jun 2024 16:23:28 +0300 Subject: Update for OTG_FS devices --- docs/reference/supported.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 5a66b7428..edb6b69ca 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -118,9 +118,9 @@ Supported MCUs | +----+------------------+--------+------+-----------+-------------------+--------------+ | | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | | | | +------------------+--------+------+-----------+-------------------+--------------+ -| | | 4x5, 4x6 | ✔ | | | dwc2 | | +| | | 4x5, 4x6 | ✔ | | ✖ | dwc2 | | | +----+------------------+--------+------+-----------+-------------------+--------------+ -| | L4+ | ✔ | | | dwc2 | | +| | L4+ | ✔ | | ✖ | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ | | L5 | ✔ | ✖ | ✖ | stm32_fsdev | | | +----+------------------+--------+------+-----------+-------------------+--------------+ -- cgit v1.3.1 From 4396ecd22cac5485ce006b330ca3ef3446d0022f Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 25 Jun 2024 11:31:19 +0700 Subject: change COMPILE_DEFINE to CFLAGS_CLI for cmake/make --- .idea/cmake.xml | 2 +- examples/build_system/make/make.mk | 4 ++++ hw/bsp/family_support.cmake | 5 ++--- hw/bsp/rp2040/family.cmake | 5 ++--- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 3c51031c1..1055e31d3 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -3,7 +3,7 @@ - + diff --git a/examples/build_system/make/make.mk b/examples/build_system/make/make.mk index a78f4130d..1500a51e0 100644 --- a/examples/build_system/make/make.mk +++ b/examples/build_system/make/make.mk @@ -109,6 +109,10 @@ INC += \ BOARD_UPPER = $(subst a,A,$(subst b,B,$(subst c,C,$(subst d,D,$(subst e,E,$(subst f,F,$(subst g,G,$(subst h,H,$(subst i,I,$(subst j,J,$(subst k,K,$(subst l,L,$(subst m,M,$(subst n,N,$(subst o,O,$(subst p,P,$(subst q,Q,$(subst r,R,$(subst s,S,$(subst t,T,$(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,$(subst z,Z,$(subst -,_,$(BOARD)))))))))))))))))))))))))))) CFLAGS += -DBOARD_$(BOARD_UPPER) +ifdef CFLAGS_CLI + CFLAGS += $(CFLAGS_CLI) +endif + # use max3421 as host controller ifeq (${MAX3421_HOST},1) SRC_C += src/portable/analog/max3421/hcd_max3421.c diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index d631c8563..9f2e34691 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -201,9 +201,8 @@ function(family_configure_common TARGET RTOS) ) # compile define from command line - if(DEFINED COMPILE_DEFINE) - #separate_arguments(COMPILE_DEFINE_LIST UNIX_COMMAND "${COMPILE_DEFINE}") - target_compile_definitions(${TARGET} PUBLIC ${COMPILE_DEFINE}) + if(DEFINED CFLAGS_CLI) + target_compile_options(${TARGET} PUBLIC ${CFLAGS_CLI}) endif() target_compile_options(${TARGET} PUBLIC ${WARNING_FLAGS_${CMAKE_C_COMPILER_ID}}) diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 5d82cbf62..c81390b28 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -176,9 +176,8 @@ function(family_configure_target TARGET RTOS) set(RTOS_SUFFIX ${RTOS_SUFFIX} PARENT_SCOPE) # compile define from command line - if(DEFINED COMPILE_DEFINE) - #separate_arguments(COMPILE_DEFINE_LIST UNIX_COMMAND "${COMPILE_DEFINE}") - target_compile_definitions(${TARGET} PUBLIC ${COMPILE_DEFINE}) + if(DEFINED CFLAGS_CLI) + target_compile_options(${TARGET} PUBLIC ${CFLAGS_CLI}) endif() pico_add_extra_outputs(${TARGET}) -- cgit v1.3.1 From b82e0a9f1ed28979e04cb5e16cb9651905dd991e Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 27 Jun 2024 20:44:40 +0200 Subject: update lpc55 bsp for rtos use. --- hw/bsp/lpc55/family.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/hw/bsp/lpc55/family.c b/hw/bsp/lpc55/family.c index cfd5b7032..f1ac86178 100644 --- a/hw/bsp/lpc55/family.c +++ b/hw/bsp/lpc55/family.c @@ -120,12 +120,17 @@ void board_init(void) { // Init 96 MHz clock BootClockFROHF96M(); +#if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); -#if CFG_TUSB_OS == OPT_OS_FREERTOS +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // Explicitly disable systick to prevent its ISR runs before scheduler start + SysTick->CTRL &= ~1U; + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(USB1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif // Init all GPIO ports @@ -239,6 +244,10 @@ void board_init(void) { // phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK); // phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06); // USBPHY->TX = phytx; + + ARM_MPU_SetMemAttr(0, 0x44); // Normal memory, non-cacheable (inner and outer) + ARM_MPU_SetRegion(0, ARM_MPU_RBAR(0x40100000, ARM_MPU_SH_NON, 0, 1, 1), ARM_MPU_RLAR(0x40104000, 0)); + ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk); #endif } -- cgit v1.3.1 From fbe025190cf65e16b756c428f84bb8b22b8aa3eb Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 27 Jun 2024 20:45:37 +0200 Subject: Make FreeRTOS config work with Cortex-M33. --- .../audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h | 1 + examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h | 1 + examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h | 1 + .../device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h | 1 + hw/bsp/lpc55/FreeRTOSConfig/FreeRTOSConfig.h | 1 + 5 files changed, 5 insertions(+) diff --git a/examples/device/audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/device/audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h index 6cc7a6577..869500ad2 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h +++ b/examples/device/audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -67,6 +67,7 @@ #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) +#define configRUN_FREERTOS_SECURE_ONLY 1 #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 diff --git a/examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h index 6cc7a6577..869500ad2 100644 --- a/examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h +++ b/examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -67,6 +67,7 @@ #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) +#define configRUN_FREERTOS_SECURE_ONLY 1 #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 diff --git a/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h index 6cc7a6577..869500ad2 100644 --- a/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h +++ b/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -67,6 +67,7 @@ #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) +#define configRUN_FREERTOS_SECURE_ONLY 1 #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 diff --git a/examples/device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h index 6cc7a6577..869500ad2 100644 --- a/examples/device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h +++ b/examples/device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -67,6 +67,7 @@ #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) +#define configRUN_FREERTOS_SECURE_ONLY 1 #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 diff --git a/hw/bsp/lpc55/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/lpc55/FreeRTOSConfig/FreeRTOSConfig.h index 6f10a7ab0..d3f357576 100644 --- a/hw/bsp/lpc55/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/lpc55/FreeRTOSConfig/FreeRTOSConfig.h @@ -52,6 +52,7 @@ #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) +#define configRUN_FREERTOS_SECURE_ONLY 1 #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 -- cgit v1.3.1 From 85e1f423bf67776bf2c7113f3f287297f6e81404 Mon Sep 17 00:00:00 2001 From: Davide Gerhard Date: Thu, 27 Jun 2024 21:30:16 +0200 Subject: remove double semicolon since ISO C not allow it ISO C does not allow extra ';' outside of a function [-Werror=pedantic] --- src/osal/osal_freertos.h | 2 +- src/typec/tcd.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index f1f05f353..a3a0f3a3f 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -78,7 +78,7 @@ typedef struct // _int_set is not used with an RTOS #define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ static _type _name##_##buf[_depth];\ - osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf, _OSAL_Q_NAME(_name) }; + osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf, _OSAL_Q_NAME(_name) } //--------------------------------------------------------------------+ // TASK API diff --git a/src/typec/tcd.h b/src/typec/tcd.h index 86499c951..bcbdab8ed 100644 --- a/src/typec/tcd.h +++ b/src/typec/tcd.h @@ -63,7 +63,7 @@ typedef struct TU_ATTR_PACKED { } xfer_complete; }; -} tcd_event_t;; +} tcd_event_t; //--------------------------------------------------------------------+ // -- cgit v1.3.1 From 6d4e2f6c16e239889195fcfbd81b4d27b6ff1979 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 27 Jun 2024 22:02:18 +0200 Subject: Fix GenID 3.10 issue on STM32L4. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 66 ++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index ffcb52f40..2871927be 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1032,21 +1032,7 @@ static void handle_rxflvl_irq(uint8_t rhport) { // XFRC complete is additionally generated when // - setup packet is received // - complete the data stage of control write is complete - if ((epnum == 0) && (bcnt == 0) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { - uint32_t doepint = epout->doepint; - - if (doepint & (DOEPINT_STPKTRX | DOEPINT_OTEPSPR)) { - // skip this "no-data" transfer complete event - // Note: STPKTRX will be clear later by setup received handler - uint32_t clear_flags = DOEPINT_XFRC; - - if (doepint & DOEPINT_OTEPSPR) clear_flags |= DOEPINT_OTEPSPR; - - epout->doepint = clear_flags; - - // TU_LOG(DWC2_DEBUG, " FIX extra transfer complete on setup/data compete\r\n"); - } - } + // It will be handled in handle_epout_irq() break; default: // Invalid @@ -1073,23 +1059,23 @@ static void handle_epout_irq(uint8_t rhport) { xfer_ctl_t* xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); - if (doepint & DOEPINT_STUP) { - // STPKTRX is only available for version from 3_00a - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_STPKTRX; - } - } else if (doepint & DOEPINT_OTEPSPR) { - epout->doepint = DOEPINT_OTEPSPR; - } else { - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_STPKTRX; + if(dma_enabled(rhport)) { + if (doepint & DOEPINT_STUP) { + // STPKTRX is only available for version from 3_00a + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_STPKTRX; + } + } else if (doepint & DOEPINT_OTEPSPR) { + epout->doepint = DOEPINT_OTEPSPR; } else { - // EP0 can only handle one packet - if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { - // Schedule another packet to be received. - edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_STPKTRX; } else { - if(dma_enabled(rhport)) { + // EP0 can only handle one packet + if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + // Schedule another packet to be received. + edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + } else { // Fix packet length uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; xfer->total_len -= remain; @@ -1097,8 +1083,24 @@ static void handle_epout_irq(uint8_t rhport) { if(n == 0 && xfer->total_len == 0) { dma_stpkt_rx(rhport); } + + dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); } + } + } + } else { + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { + epout->doepint = DOEPINT_STPKTRX; + } else { + if ((doepint & DOEPINT_OTEPSPR) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { + epout->doepint = DOEPINT_OTEPSPR; + } + // EP0 can only handle one packet + if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + // Schedule another packet to be received. + edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + } else { dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); } } @@ -1108,10 +1110,10 @@ static void handle_epout_irq(uint8_t rhport) { // SETUP packet Setup Phase done. if (doepint & DOEPINT_STUP) { epout->doepint = DOEPINT_STUP; - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { epout->doepint = DOEPINT_STPKTRX; } - if(dma_enabled(rhport) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { + if(dma_enabled(rhport) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { dma_stpkt_rx(rhport); } -- cgit v1.3.1 From 8f699023f3ff2434efa4433ddc92a9c01756d1f1 Mon Sep 17 00:00:00 2001 From: Davide Gerhard Date: Fri, 28 Jun 2024 10:55:43 +0200 Subject: audio_device.c: fix strict-overflow warning with gcc >= 12 Fix the following error ~/libs/tinyusb/src/class/audio/audio_device.c:1493:23: error: assuming pointer wraparound does not occur when comparing P +- C1 with P +- C2 [-Werror=strict-overflow] 1493 | while (p_desc < p_desc_end) | ~~~~~~~^~~~~~~~~~~~ compilation terminated due to -Wfatal-errors. --- src/class/audio/audio_device.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 46db96ea9..65cac2fd5 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1490,7 +1490,8 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin #endif uint8_t const *p_desc = _audiod_fct[i].p_desc; uint8_t const *p_desc_end = p_desc + _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { @@ -1740,7 +1741,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * uint8_t const *p_desc_end = audio->p_desc + audio->desc_length - TUD_AUDIO_DESC_IAD_LEN; // p_desc starts at required interface with alternate setting zero - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { // Find correct interface if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bInterfaceNumber == itf && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == alt) @@ -1750,7 +1752,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #endif // From this point forward follow the EP descriptors associated to the current alternate setting interface - Open EPs if necessary uint8_t foundEPs = 0, nEps = ((tusb_desc_interface_t const * )p_desc)->bNumEndpoints; - while (foundEPs < nEps && p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (foundEPs < nEps && (p_desc_end - p_desc > 0)) { if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { @@ -2394,7 +2397,8 @@ static bool audiod_get_AS_interface_index(uint8_t itf, audiod_function_t * audio p_desc += ((audio_desc_cs_ac_interface_t const *)p_desc)->wTotalLength; uint8_t tmp = 0; - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { // We assume the number of alternate settings is increasing thus we return the index of alternate setting zero! if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == 0) @@ -2447,7 +2451,8 @@ static bool audiod_verify_entity_exists(uint8_t itf, uint8_t entityID, uint8_t * uint8_t const *p_desc_end = ((audio_desc_cs_ac_interface_t const *)p_desc)->wTotalLength + p_desc; p_desc = tu_desc_next(p_desc); // Get past CS AC descriptor - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { if (p_desc[3] == entityID) // Entity IDs are always at offset 3 { @@ -2471,8 +2476,8 @@ static bool audiod_verify_itf_exists(uint8_t itf, uint8_t *func_id) // Get pointer at beginning and end uint8_t const *p_desc = _audiod_fct[i].p_desc; uint8_t const *p_desc_end = _audiod_fct[i].p_desc + _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; - - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const *)_audiod_fct[i].p_desc)->bInterfaceNumber == itf) { @@ -2500,7 +2505,8 @@ static bool audiod_verify_ep_exists(uint8_t ep, uint8_t *func_id) uint8_t const *p_desc = tu_desc_next(_audiod_fct[i].p_desc); p_desc += ((audio_desc_cs_ac_interface_t const *)p_desc)->wTotalLength; - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT && ((tusb_desc_endpoint_t const * )p_desc)->bEndpointAddress == ep) { @@ -2531,8 +2537,8 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #endif p_desc = tu_desc_next(p_desc); // Exclude standard AS interface descriptor of current alternate interface descriptor - - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { // Abort if follow up descriptor is a new standard interface descriptor - indicates the last AS descriptor was already finished if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) break; -- cgit v1.3.1 From 8f9a57636c9ae6b51e272274ea79f01a7a2631c1 Mon Sep 17 00:00:00 2001 From: Davide Gerhard Date: Fri, 28 Jun 2024 19:57:59 +0200 Subject: audio.h: fix error ISO C restricts enumerator values to range of 'int' fix error ~/dsp/libs/tinyusb/src/class/audio/audio.h:643:53: error: ISO C restricts enumerator values to range of 'int' before C23 [-Werror=pedantic] 643 | AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000, // TODO | ^~~~~~~~~~ compilation terminated due to -Wfatal-errors. Closes: https://github.com/hathach/tinyusb/issues/2690 --- src/class/audio/audio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index d6f3e22e2..49ccbe863 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -489,7 +489,7 @@ typedef enum AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2), AUDIO_DATA_FORMAT_TYPE_I_ALAW = (uint32_t) (1 << 3), AUDIO_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4), - AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000, + AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = (int)(1U << 31U), } audio_data_format_type_I_t; /// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification @@ -640,7 +640,7 @@ typedef enum AUDIO_CHANNEL_CONFIG_BOTTOM_CENTER = 0x01000000, AUDIO_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000, AUDIO_CHANNEL_CONFIG_BACK_RIGHT_OF_CENTER = 0x04000000, - AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000, + AUDIO_CHANNEL_CONFIG_RAW_DATA = (int)(1U << 31U), } audio_channel_config_t; /// AUDIO Channel Cluster Descriptor (4.1) -- cgit v1.3.1 From 0f288326cc80dba192d08b74116aa0be91a81a6f Mon Sep 17 00:00:00 2001 From: Brent Kowal Date: Fri, 28 Jun 2024 16:55:27 -0400 Subject: Initial Commit for MAX32 Support Initial commit for the port of TUSB to MAX32xxx parts, staring with MAX32690 - Added dcd_max32.c (based on dcd_musb.c) for interfacing with the peripheral - Added MAX32690 part family support - Added max32690evkit board support - Updated examples for unique EP number requirement - Updated get_deps.py to fetch the MSDK Known Issues / Additional Testing Required - msc_dual_lun only shown 1 volume on Windows - USBTMC does not have a valid Windowsdriver - DFU does not have a valid Windows driver - WebUSB is "Device not Recognized" - Need to test build scripts with IAR and Clang --- examples/device/cdc_msc/src/usb_descriptors.c | 10 + .../device/cdc_msc_freertos/src/usb_descriptors.c | 10 + examples/device/cdc_uac2/src/usb_descriptors.c | 10 + .../dynamic_configuration/src/usb_descriptors.c | 13 + examples/device/midi_test/src/usb_descriptors.c | 4 + examples/device/msc_dual_lun/src/usb_descriptors.c | 6 + .../device/net_lwip_webserver/src/tusb_config.h | 2 + .../net_lwip_webserver/src/usb_descriptors.c | 7 + examples/device/uac2_headset/src/usb_descriptors.c | 7 + .../device/webusb_serial/src/usb_descriptors.c | 7 + hw/bsp/board_mcu.h | 3 + hw/bsp/max32690/FreeRTOSConfig/FreeRTOSConfig.h | 149 ++++ hw/bsp/max32690/boards/max32690evkit/board.cmake | 1 + hw/bsp/max32690/boards/max32690evkit/board.h | 56 ++ hw/bsp/max32690/boards/max32690evkit/board.mk | 1 + hw/bsp/max32690/family.c | 159 ++++ hw/bsp/max32690/family.cmake | 152 ++++ hw/bsp/max32690/family.mk | 106 +++ hw/bsp/max32690/max32690.ld | 162 ++++ src/common/tusb_mcu.h | 8 + src/portable/analog/max32/dcd_max32.c | 841 +++++++++++++++++++++ src/tusb_option.h | 3 + tools/get_deps.py | 3 + 23 files changed, 1720 insertions(+) create mode 100644 hw/bsp/max32690/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/max32690/boards/max32690evkit/board.cmake create mode 100644 hw/bsp/max32690/boards/max32690evkit/board.h create mode 100644 hw/bsp/max32690/boards/max32690evkit/board.mk create mode 100644 hw/bsp/max32690/family.c create mode 100644 hw/bsp/max32690/family.cmake create mode 100644 hw/bsp/max32690/family.mk create mode 100644 hw/bsp/max32690/max32690.ld create mode 100644 src/portable/analog/max32/dcd_max32.c diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c index 2afa24903..1ca614f4e 100644 --- a/examples/device/cdc_msc/src/usb_descriptors.c +++ b/examples/device/cdc_msc/src/usb_descriptors.c @@ -125,6 +125,16 @@ enum { #define EPNUM_MSC_OUT 0x04 #define EPNUM_MSC_IN 0x85 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x83 + + #define EPNUM_MSC_OUT 0x04 + #define EPNUM_MSC_IN 0x85 + #else #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 diff --git a/examples/device/cdc_msc_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_freertos/src/usb_descriptors.c index 9c29701c7..f563e80d3 100644 --- a/examples/device/cdc_msc_freertos/src/usb_descriptors.c +++ b/examples/device/cdc_msc_freertos/src/usb_descriptors.c @@ -106,6 +106,16 @@ enum #define EPNUM_MSC_OUT 0x04 #define EPNUM_MSC_IN 0x85 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x83 + + #define EPNUM_MSC_OUT 0x04 + #define EPNUM_MSC_IN 0x85 + #else #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 diff --git a/examples/device/cdc_uac2/src/usb_descriptors.c b/examples/device/cdc_uac2/src/usb_descriptors.c index 72a695622..43e8cf3d7 100644 --- a/examples/device/cdc_uac2/src/usb_descriptors.c +++ b/examples/device/cdc_uac2/src/usb_descriptors.c @@ -117,6 +117,16 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_CDC_OUT 0x04 #define EPNUM_CDC_IN 0x85 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_AUDIO_IN 0x01 + #define EPNUM_AUDIO_OUT 0x02 + + #define EPNUM_CDC_NOTIF 0x83 + #define EPNUM_CDC_OUT 0x04 + #define EPNUM_CDC_IN 0x85 + #else #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x01 diff --git a/examples/device/dynamic_configuration/src/usb_descriptors.c b/examples/device/dynamic_configuration/src/usb_descriptors.c index 7f35b4b22..eebdd4f69 100644 --- a/examples/device/dynamic_configuration/src/usb_descriptors.c +++ b/examples/device/dynamic_configuration/src/usb_descriptors.c @@ -158,6 +158,19 @@ enum #define EPNUM_1_MSC_OUT 0x01 #define EPNUM_1_MSC_IN 0x82 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // FT9XX doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_0_CDC_NOTIF 0x81 + #define EPNUM_0_CDC_OUT 0x02 + #define EPNUM_0_CDC_IN 0x83 + + #define EPNUM_0_MIDI_OUT 0x04 + #define EPNUM_0_MIDI_IN 0x85 + + #define EPNUM_1_MSC_OUT 0x01 + #define EPNUM_1_MSC_IN 0x82 + #else #define EPNUM_0_CDC_NOTIF 0x81 #define EPNUM_0_CDC_OUT 0x02 diff --git a/examples/device/midi_test/src/usb_descriptors.c b/examples/device/midi_test/src/usb_descriptors.c index 9781d3d6f..797b50ab2 100644 --- a/examples/device/midi_test/src/usb_descriptors.c +++ b/examples/device/midi_test/src/usb_descriptors.c @@ -90,6 +90,10 @@ enum // On Bridgetek FT9xx endpoint numbers must be unique... #define EPNUM_MIDI_OUT 0x02 #define EPNUM_MIDI_IN 0x03 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // On MAX32 endpoint numbers must be unique... + #define EPNUM_MIDI_OUT 0x02 + #define EPNUM_MIDI_IN 0x03 #else #define EPNUM_MIDI_OUT 0x01 #define EPNUM_MIDI_IN 0x01 diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c index c0610945f..e32466228 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -97,6 +97,12 @@ enum #define EPNUM_MSC_OUT 0x01 #define EPNUM_MSC_IN 0x82 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_MSC_OUT 0x01 + #define EPNUM_MSC_IN 0x82 + #else #define EPNUM_MSC_OUT 0x01 #define EPNUM_MSC_IN 0x81 diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h index d3e094517..2f641f33e 100644 --- a/examples/device/net_lwip_webserver/src/tusb_config.h +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -91,6 +91,8 @@ extern "C" { #define USE_ECM 1 #elif TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F1) #define USE_ECM 1 +#elif TU_CHECK_MCU(OPT_MCU_MAX32690) + #define USE_ECM 1 #else #define USE_ECM 0 #define INCLUDE_IPERF diff --git a/examples/device/net_lwip_webserver/src/usb_descriptors.c b/examples/device/net_lwip_webserver/src/usb_descriptors.c index da628c8be..ba30b869e 100644 --- a/examples/device/net_lwip_webserver/src/usb_descriptors.c +++ b/examples/device/net_lwip_webserver/src/usb_descriptors.c @@ -120,6 +120,13 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_NET_OUT 0x02 #define EPNUM_NET_IN 0x83 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_NET_NOTIF 0x81 + #define EPNUM_NET_OUT 0x02 + #define EPNUM_NET_IN 0x83 + #else #define EPNUM_NET_NOTIF 0x81 #define EPNUM_NET_OUT 0x02 diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c index ff4dc2acc..bfc8a4ab5 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -104,6 +104,13 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_AUDIO_OUT 0x02 #define EPNUM_AUDIO_INT 0x03 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_AUDIO_IN 0x01 + #define EPNUM_AUDIO_OUT 0x02 + #define EPNUM_AUDIO_INT 0x03 + #else #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x01 diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c index b01fae8e3..bcfbe590e 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.c +++ b/examples/device/webusb_serial/src/usb_descriptors.c @@ -105,6 +105,13 @@ enum #define EPNUM_CDC_OUT 3 #define EPNUM_VENDOR_IN 4 #define EPNUM_VENDOR_OUT 5 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_IN 2 + #define EPNUM_CDC_OUT 3 + #define EPNUM_VENDOR_IN 4 + #define EPNUM_VENDOR_OUT 5 #else #define EPNUM_CDC_IN 2 #define EPNUM_CDC_OUT 2 diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index 013eb1c83..436164c35 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -170,6 +170,9 @@ #elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) // no header needed +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + #include "max32690.h" + #else #error "Missing MCU header" #endif diff --git a/hw/bsp/max32690/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/max32690/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..e5a76af85 --- /dev/null +++ b/hw/bsp/max32690/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "mxc_device.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS __NVIC_PRIO_BITS + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<ldoctrl |= MXC_F_MCR_LDOCTRL_0P9EN; + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB); + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_USB); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { + #if LED_STATE_ON + state = !state; + #endif + if(state) { + MXC_GPIO_OutClr(LED_PORT, LED_PIN); + } else { + MXC_GPIO_OutSet(LED_PORT, LED_PIN); + } +} + +uint32_t board_button_read(void) { + uint32_t state = MXC_GPIO_InGet(BUTTON_PORT, BUTTON_PIN) ? 1 : 0; + return BUTTON_STATE_ACTIVE == state; +} + +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN]; //USN Buffer + /* All other 2nd parameter is optional checkum buffer */ + MXC_SYS_GetUSN(hw_id, NULL); + + size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN); + memcpy(id, hw_id, act_len); + return act_len; +} + +int board_uart_read(uint8_t *buf, int len) { + int uart_val; + int act_len = 0; + + while( act_len < len ) { + if((uart_val = MXC_UART_ReadCharacterRaw(ConsoleUart)) == E_UNDERFLOW) { + break; + } else { + *buf++ = (uint8_t)uart_val; + act_len++; + } + } + return act_len; +} + +int board_uart_write(void const *buf, int len) { + int act_len = 0; + const uint8_t* ch_ptr = (const uint8_t*)buf; + while(act_len < len){ + MXC_UART_WriteCharacter(ConsoleUart, *ch_ptr++); + act_len++; + } + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; +} + +uint32_t board_millis(void) { + return system_ticks; +} +#endif + +void HardFault_Handler(void) { + __asm("BKPT #0\n"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) { +} diff --git a/hw/bsp/max32690/family.cmake b/hw/bsp/max32690/family.cmake new file mode 100644 index 000000000..e1d797f58 --- /dev/null +++ b/hw/bsp/max32690/family.cmake @@ -0,0 +1,152 @@ +include_guard() + +set(MAX32_PERIPH ${TOP}/hw/mcu/analog/max32/Libraries/PeriphDrivers) +set(MAX32_CMSIS ${TOP}/hw/mcu/analog/max32/Libraries/CMSIS) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# Get the linker file from current location (family) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max32690.ld) +set(LD_FILE_Clang ${LD_FILE_GNU}) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(JLINK_DEVICE max32690) + +set(FAMILY_MCUS MAX32690 CACHE INTERNAL "") + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + TARGET=MAX32690 + TARGET_REV=0x4131 + MXC_ASSERT_ENABLE + MAX32690 + FLASH_ORIGIN=0x10000000 + FLASH_SIZE=0x340000 + SRAM_ORIGIN=0x20000000 + SRAM_SIZE=0x100000 + IAR_PRAGMAS=0 + CFG_TUSB_MCU=OPT_MCU_MAX32690 + BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + ) +endfunction() + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + # Startup & Linker script + set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX32690/Source/GCC/startup_max32690.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${MAX32_CMSIS}/Device/Maxim/MAX32690/Source/IAR/startup_max32690.s) + + set(PERIPH_SRC ${MAX32_PERIPH}/Source) + add_library(${BOARD_TARGET} STATIC + ${MAX32_CMSIS}/Device/Maxim/MAX32690/Source/heap.c + ${MAX32_CMSIS}/Device/Maxim/MAX32690/Source/system_max32690.c + ${PERIPH_SRC}/SYS/mxc_assert.c + ${PERIPH_SRC}/SYS/mxc_delay.c + ${PERIPH_SRC}/SYS/mxc_lock.c + ${PERIPH_SRC}/SYS/nvic_table.c + ${PERIPH_SRC}/SYS/pins_me18.c + ${PERIPH_SRC}/SYS/sys_me18.c + ${PERIPH_SRC}/CTB/ctb_me18.c + ${PERIPH_SRC}/CTB/ctb_reva.c + ${PERIPH_SRC}/CTB/ctb_common.c + ${PERIPH_SRC}/FLC/flc_common.c + ${PERIPH_SRC}/FLC/flc_me18.c + ${PERIPH_SRC}/FLC/flc_reva.c + ${PERIPH_SRC}/GPIO/gpio_common.c + ${PERIPH_SRC}/GPIO/gpio_me18.c + ${PERIPH_SRC}/GPIO/gpio_reva.c + ${PERIPH_SRC}/ICC/icc_me18.c + ${PERIPH_SRC}/ICC/icc_reva.c + ${PERIPH_SRC}/UART/uart_common.c + ${PERIPH_SRC}/UART/uart_me18.c + ${PERIPH_SRC}/UART/uart_revb.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${MAX32_CMSIS}/Include + ${MAX32_CMSIS}/Device/Maxim/MAX32690/Include + ${MAX32_PERIPH}/Include/MAX32690 + ${PERIPH_SRC}/SYS + ${PERIPH_SRC}/GPIO + ${PERIPH_SRC}/CTB + ${PERIPH_SRC}/ICC + ${PERIPH_SRC}/FLC + ${PERIPH_SRC}/UART + ) + + target_compile_options(${TARGET} PRIVATE + -Wno-error=strict-prototypes + ) + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_MAX32690 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/analog/max32/dcd_max32.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + target_compile_options(${TARGET}-tinyusb PRIVATE + -Wno-error=strict-prototypes + ) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/max32690/family.mk b/hw/bsp/max32690/family.mk new file mode 100644 index 000000000..08d5e8671 --- /dev/null +++ b/hw/bsp/max32690/family.mk @@ -0,0 +1,106 @@ +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/analog/max32 + +# Important locations in the hw support for MCU +MAX32_CMSIS = hw/mcu/analog/max32/Libraries/CMSIS +MAX32_PERIPH = hw/mcu/analog/max32/Libraries/PeriphDrivers + +# Add any board specific make rules +include $(TOP)/$(BOARD_PATH)/board.mk + +CPU_CORE ?= cortex-m4 +PORT ?= 0 + +# GCC +SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/GCC/startup_max32690.s +LD_FILE = $(FAMILY_PATH)/max32690.ld + +# IAR +SRC_S_IAR += $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/IAR/startup_max32690.s + +# -------------- +# Compiler Flags +# -------------- +# Flags for the MAX32690 SDK +CFLAGS += -DTARGET=MAX32690 \ + -DTARGET_REV=0x4131 \ + -DMXC_ASSERT_ENABLE \ + -DMAX32690 \ + -DFLASH_ORIGIN=0x10000000 \ + -DFLASH_SIZE=0x340000 \ + -DSRAM_ORIGIN=0x20000000 \ + -DSRAM_SIZE=0x100000 \ + -DIAR_PRAGMAS=0 + +# Flags for TUSB features +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_MAX32690 \ + -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + +# mcu driver cause following warnings +CFLAGS += -Wno-error=unused-parameter \ + -Wno-error=strict-prototypes \ + -Wno-error=old-style-declaration \ + -Wno-error=sign-compare \ + -Wno-error=cast-qual \ + -Wno-lto-type-mismatch + +LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs + +# For flash-jlink target +JLINK_DEVICE = max32690 + +# flash target using Jlik +flash: flash-jlink + +# Optional flash option when running within an installed MSDK to use OpenOCD +# Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated. +# If the MSDK is installed, flash-msdk can be run to utilize the the modified +# openocd with the algorithms +MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) +flash-msdk: + $(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \ + -f interface/cmsis-dap.cfg -f target/max32690.cfg \ + -c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit" + +# ----------------- +# Sources & Include +# ----------------- +PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source +SRC_C += \ + src/portable/analog/max32/dcd_max32.c \ + $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/heap.c \ + $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/system_max32690.c \ + $(PERIPH_SRC)/SYS/mxc_assert.c \ + $(PERIPH_SRC)/SYS/mxc_delay.c \ + $(PERIPH_SRC)/SYS/mxc_lock.c \ + $(PERIPH_SRC)/SYS/nvic_table.c \ + $(PERIPH_SRC)/SYS/pins_me18.c \ + $(PERIPH_SRC)/SYS/sys_me18.c \ + $(PERIPH_SRC)/CTB/ctb_me18.c \ + $(PERIPH_SRC)/CTB/ctb_reva.c \ + $(PERIPH_SRC)/CTB/ctb_common.c \ + $(PERIPH_SRC)/FLC/flc_common.c \ + $(PERIPH_SRC)/FLC/flc_me18.c \ + $(PERIPH_SRC)/FLC/flc_reva.c \ + $(PERIPH_SRC)/GPIO/gpio_common.c \ + $(PERIPH_SRC)/GPIO/gpio_me18.c \ + $(PERIPH_SRC)/GPIO/gpio_reva.c \ + $(PERIPH_SRC)/ICC/icc_me18.c \ + $(PERIPH_SRC)/ICC/icc_reva.c \ + $(PERIPH_SRC)/UART/uart_common.c \ + $(PERIPH_SRC)/UART/uart_me18.c \ + $(PERIPH_SRC)/UART/uart_revb.c \ + + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(MAX32_CMSIS)/Include \ + $(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX32690/Include \ + $(TOP)/$(MAX32_PERIPH)/Include/MAX32690 \ + $(PERIPH_SRC)/SYS \ + $(PERIPH_SRC)/GPIO \ + $(PERIPH_SRC)/CTB \ + $(PERIPH_SRC)/ICC \ + $(PERIPH_SRC)/FLC \ + $(PERIPH_SRC)/UART diff --git a/hw/bsp/max32690/max32690.ld b/hw/bsp/max32690/max32690.ld new file mode 100644 index 000000000..35886fe3a --- /dev/null +++ b/hw/bsp/max32690/max32690.ld @@ -0,0 +1,162 @@ +MEMORY { + ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00020000 /* 128kB ROM */ + FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x00340000 + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00100000 + + /* + * Note that CS0/CS1 address mappings may be reversed using MXC_HPC->mbr0 and ->mbr1 + * The following mappings are selected for simplicity + */ + HPB_CS0 (rwx) : ORIGIN = 0x60000000, LENGTH = 0x10000000 /* External Hyperbus/Xccelabus chip select 0 */ + HPB_CS1 (rwx) : ORIGIN = 0x70000000, LENGTH = 0x10000000 /* External Hyperbus/Xccelabus chip select 1 */ +} + +SECTIONS { + .rom : + { + KEEP(*(.rom_vector)) + *(.rom_handlers*) + } > ROM + + .text : + { + _text = .; + KEEP(*(.isr_vector)) + EXCLUDE_FILE (*riscv.o) *(.text*) /* program code, exclude RISCV code */ + *(.rodata*) /* read-only data: "const" */ + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + /* C++ Exception handling */ + KEEP(*(.eh_frame*)) + _etext = .; + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + /* These sections allow code to be compiled/linked for HPB addresses, but reside in + * flash until copied by code to the external HPB flash device + */ + .hpb_cs0_section : + { + __hpb_cs0_start = ABSOLUTE(.); + KEEP(*(.hpb_cs0_section*)) + } > HPB_CS0 AT>FLASH + + __load_start_hpb_cs0 = LOADADDR(.hpb_cs0_section); + __load_length_hpb_cs0 = SIZEOF(.hpb_cs0_section); + + .hpb_cs1_section : + { + __hpb_cs1_start = ABSOLUTE(.); + KEEP(*(.hpb_cs1_section*)) + } > HPB_CS1 AT>FLASH + + __load_start_hpb_cs1 = LOADADDR(.hpb_cs1_section); + __load_length_hpb_cs1 = SIZEOF(.hpb_cs1_section); + + /* Binary import */ + .bin_storage : + { + FILL(0xFF) + _bin_start_ = .; + KEEP(*(.bin_storage_img)) + _bin_end_ = .; + . = ALIGN(4); + } > FLASH + + /* it's used for C++ exception handling */ + /* we need to keep this to avoid overlapping */ + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + .data : + { + _data = ALIGN(., 4); + *(vtable) + *(.data*) /*read-write initialized data: initialized global variable*/ + + /* These array sections are used by __libc_init_array to call static C++ constructors */ + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + /* Run the flash programming functions from SRAM */ + *(.flashprog) + + _edata = ALIGN(., 4); + } > SRAM AT>FLASH + __load_data = LOADADDR(.data); + + .bss : + { + . = ALIGN(4); + _bss = .; + *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(COMMON) + _ebss = ALIGN(., 4); + } > SRAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(SRAM) + LENGTH(SRAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > SRAM + + .heap (COPY): + { + . = ALIGN(4); + *(.heap*) + __HeapLimit = ABSOLUTE(__StackLimit); + } > SRAM + + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack") +} diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index c66996c4f..a68e160bd 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -452,6 +452,14 @@ #define TUP_RHPORT_HIGHSPEED CFG_TUD_WCH_USBIP_USBHS #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_WCH_USBIP_USBHS ? 16 : 8) +//--------------------------------------------------------------------+ +// Analog Devices +//--------------------------------------------------------------------+ +#elif TU_CHECK_MCU(OPT_MCU_MAX32690) + #define TUP_DCD_ENDPOINT_MAX 12 + #define TUP_RHPORT_HIGHSPEED 1 + + #endif //--------------------------------------------------------------------+ diff --git a/src/portable/analog/max32/dcd_max32.c b/src/portable/analog/max32/dcd_max32.c new file mode 100644 index 000000000..150d476fa --- /dev/null +++ b/src/portable/analog/max32/dcd_max32.c @@ -0,0 +1,841 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Koji KITAYAMA + * Copyright (c) 2024 Brent Kowal (Analog Devices, Inc) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && TU_CHECK_MCU(OPT_MCU_MAX32690) + +#if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) +/* GCC warns that an address may be unaligned, even though + * the target CPU has the capability for unaligned memory access. */ +_Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); +#endif + +#include "device/dcd.h" + +#include "mxc_delay.h" +#include "mxc_device.h" +#include "mxc_sys.h" +#include "nvic_table.h" +#include "usbhs_regs.h" + +#define USBHS_M31_CLOCK_RECOVERY + +/*------------------------------------------------------------------ + * MACRO TYPEDEF CONSTANT ENUM DECLARATION + *------------------------------------------------------------------*/ +#define REQUEST_TYPE_INVALID (0xFFu) + + +typedef union { + uint8_t u8; + uint16_t u16; + uint32_t u32; +} hw_fifo_t; + +typedef struct TU_ATTR_PACKED +{ + void *buf; /* the start address of a transfer data buffer */ + uint16_t length; /* the number of bytes in the buffer */ + uint16_t remaining; /* the number of bytes remaining in the buffer */ +} pipe_state_t; + +typedef struct +{ + tusb_control_request_t setup_packet; + uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ + int8_t status_out; + pipe_state_t pipe0; + pipe_state_t pipe[2][TUP_DCD_ENDPOINT_MAX - 1]; /* pipe[direction][endpoint number - 1] */ + uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ +} dcd_data_t; + +/*------------------------------------------------------------------ + * INTERNAL OBJECT & FUNCTION DECLARATION + *------------------------------------------------------------------*/ +static dcd_data_t _dcd; + + +static volatile void* edpt_get_fifo_ptr(unsigned epnum) +{ + volatile uint32_t *ptr; + + ptr = &MXC_USBHS->fifo0; + ptr += epnum; /* Pointer math: multiplies ep by sizeof(uint32_t) */ + + return (volatile void *)ptr; +} + +static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) +{ + volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; + uintptr_t addr = (uintptr_t)buf; + while (len >= 4) { + reg->u32 = *(uint32_t const *)addr; + addr += 4; + len -= 4; + } + if (len >= 2) { + reg->u16 = *(uint16_t const *)addr; + addr += 2; + len -= 2; + } + if (len) { + reg->u8 = *(uint8_t const *)addr; + } +} + +static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) +{ + volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; + uintptr_t addr = (uintptr_t)buf; + while (len >= 4) { + *(uint32_t *)addr = reg->u32; + addr += 4; + len -= 4; + } + if (len >= 2) { + *(uint16_t *)addr = reg->u16; + addr += 2; + len -= 2; + } + if (len) { + *(uint8_t *)addr = reg->u8; + } +} + +static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir) +{ + static const struct { + void (*tu_fifo_get_info)(tu_fifo_t *f, tu_fifo_buffer_info_t *info); + void (*tu_fifo_advance)(tu_fifo_t *f, uint16_t n); + void (*pipe_read_write)(void *buf, volatile void *fifo, unsigned len); + } ops[] = { + /* OUT */ {tu_fifo_get_write_info,tu_fifo_advance_write_pointer,pipe_read_packet}, + /* IN */ {tu_fifo_get_read_info, tu_fifo_advance_read_pointer, pipe_write_packet}, + }; + tu_fifo_buffer_info_t info; + ops[dir].tu_fifo_get_info(f, &info); + unsigned total_len = len; + len = TU_MIN(total_len, info.len_lin); + ops[dir].pipe_read_write(info.ptr_lin, fifo, len); + unsigned rem = total_len - len; + if (rem) { + len = TU_MIN(rem, info.len_wrap); + ops[dir].pipe_read_write(info.ptr_wrap, fifo, len); + rem -= len; + } + ops[dir].tu_fifo_advance(f, total_len - rem); +} + +static void process_setup_packet(uint8_t rhport) +{ + uint32_t *p = (void*)&_dcd.setup_packet; + p[0] = MXC_USBHS->fifo0; + p[1] = MXC_USBHS->fifo0; + + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; + _dcd.pipe0.remaining = 0; + dcd_event_setup_received(rhport, (const uint8_t*)(uintptr_t)&_dcd.setup_packet, true); + + const unsigned len = _dcd.setup_packet.wLength; + _dcd.remaining_ctrl = len; + const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); + /* Clear RX FIFO and reverse the transaction direction */ + if (len && dir_in) { + MXC_USBHS->index = 0; + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY; + } +} + +static bool handle_xfer_in(uint_fast8_t ep_addr) +{ + unsigned epnum = tu_edpt_number(ep_addr); + unsigned epnum_minus1 = epnum - 1; + pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + const unsigned rem = pipe->remaining; + + //This function should not be for ep0 + TU_ASSERT(epnum); + + if (!rem) { + pipe->buf = NULL; + return true; + } + + MXC_USBHS->index = epnum; + const unsigned mps = MXC_USBHS->inmaxp; + const unsigned len = TU_MIN(mps, rem); + void *buf = pipe->buf; + volatile void* fifo_ptr = edpt_get_fifo_ptr(epnum); + // TU_LOG1(" %p mps %d len %d rem %d\r\n", buf, mps, len, rem); + if (len) { + if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { + pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_IN); + } else { + pipe_write_packet(buf,fifo_ptr, len); + pipe->buf = buf + len; + } + pipe->remaining = rem - len; + } + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_INPKTRDY; //TODO: Verify a | isnt needed + + return false; +} + +static bool handle_xfer_out(uint_fast8_t ep_addr) +{ + unsigned epnum = tu_edpt_number(ep_addr); + unsigned epnum_minus1 = epnum - 1; + pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + + //This function should not be for ep0 + TU_ASSERT(epnum); + + MXC_USBHS->index = epnum; + + TU_ASSERT(MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY); + + const unsigned mps = MXC_USBHS->outmaxp; + const unsigned rem = pipe->remaining; + const unsigned vld = MXC_USBHS->outcount; + const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + void *buf = pipe->buf; + volatile void* fifo_ptr = edpt_get_fifo_ptr(epnum); + if (len) { + if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { + pipe_read_write_packet_ff(buf,fifo_ptr, len, TUSB_DIR_OUT); + } else { + pipe_read_packet(buf, fifo_ptr, len); + pipe->buf = buf + len; + } + pipe->remaining = rem - len; + } + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return NULL != buf; + } + MXC_USBHS->outcsrl = 0; /* Clear RXRDY bit */ //TODO: Verify just setting to 0 is ok + return false; +} + +static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void)rhport; + + unsigned epnum = tu_edpt_number(ep_addr); + unsigned epnum_minus1 = epnum - 1; + unsigned dir_in = tu_edpt_dir(ep_addr); + + pipe_state_t *pipe = &_dcd.pipe[dir_in][epnum_minus1]; + pipe->buf = buffer; + pipe->length = total_bytes; + pipe->remaining = total_bytes; + + if (dir_in) { + handle_xfer_in(ep_addr); + } else { + MXC_USBHS->index = epnum; + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY){ + MXC_USBHS->outcsrl = 0; //TODO: Verify just setting to 0 is ok + } + } + return true; +} + +static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void)rhport; + TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ + + const unsigned req = _dcd.setup_packet.bmRequestType; + TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); + + if (req == REQUEST_TYPE_INVALID || _dcd.status_out) { + /* STATUS OUT stage. + * MUSB controller automatically handles STATUS OUT packets without + * software helps. We do not have to do anything. And STATUS stage + * may have already finished and received the next setup packet + * without calling this function, so we have no choice but to + * invoke the callback function of status packet here. */ + _dcd.status_out = 0; + if (req == REQUEST_TYPE_INVALID) { + dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); + } else { + /* The next setup packet has already been received, it aborts + * invoking callback function to avoid confusing TUSB stack. */ + TU_LOG1("Drop CONTROL_STAGE_ACK\r\n"); + } + return true; + } + const unsigned dir_in = tu_edpt_dir(ep_addr); + MXC_USBHS->index = 0; + if (tu_edpt_dir(req) == dir_in) { /* DATA stage */ + TU_ASSERT(total_bytes <= _dcd.remaining_ctrl); + const unsigned rem = _dcd.remaining_ctrl; + const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes); + volatile void* fifo_ptr = edpt_get_fifo_ptr(0); + if (dir_in) { + pipe_write_packet(buffer, fifo_ptr, len); + + _dcd.pipe0.buf = buffer + len; + _dcd.pipe0.length = len; + _dcd.pipe0.remaining = 0; + + _dcd.remaining_ctrl = rem - len; + if ((len < 64) || (rem == len)) { + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ + _dcd.status_out = 1; + /* Flush TX FIFO and reverse the transaction direction. */ + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_INPKTRDY | MXC_F_USBHS_CSR0_DATA_END; + } else { + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_INPKTRDY; /* Flush TX FIFO to return ACK. */ + } + } else { + _dcd.pipe0.buf = buffer; + _dcd.pipe0.length = len; + _dcd.pipe0.remaining = len; + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY; /* Clear RX FIFO to return ACK. */ + } + } else if (dir_in) { + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; + _dcd.pipe0.remaining = 0; + /* Clear RX FIFO and reverse the transaction direction */ + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY | MXC_F_USBHS_CSR0_DATA_END; + } + return true; +} + +static void process_ep0(uint8_t rhport) +{ + MXC_USBHS->index = 0; + uint_fast8_t csrl = MXC_USBHS->csr0; + + if (csrl & MXC_F_USBHS_CSR0_SENT_STALL) { + /* Returned STALL packet to HOST. */ + MXC_USBHS->csr0 = 0; /* Clear STALL */ + return; + } + + unsigned req = _dcd.setup_packet.bmRequestType; + if (csrl & MXC_F_USBHS_CSR0_SETUP_END) { + TU_LOG1(" ABORT by the next packets\r\n"); + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_SETUP_END; + if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { + /* DATA stage was aborted by receiving STATUS or SETUP packet. */ + _dcd.pipe0.buf = NULL; + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + dcd_event_xfer_complete(rhport, + req & TUSB_DIR_IN_MASK, + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } + req = REQUEST_TYPE_INVALID; + if (!(csrl & MXC_F_USBHS_CSR0_OUTPKTRDY)) return; /* Received SETUP packet */ + } + + if (csrl & MXC_F_USBHS_CSR0_OUTPKTRDY) { + /* Received SETUP or DATA OUT packet */ + if (req == REQUEST_TYPE_INVALID) { + /* SETUP */ + TU_ASSERT(sizeof(tusb_control_request_t) == MXC_USBHS->count0,); + process_setup_packet(rhport); + return; + } + if (_dcd.pipe0.buf) { + /* DATA OUT */ + const unsigned vld = MXC_USBHS->count0; + const unsigned rem = _dcd.pipe0.remaining; + const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); + volatile void* fifo_ptr = edpt_get_fifo_ptr(0); + pipe_read_packet(_dcd.pipe0.buf, fifo_ptr, len); + + _dcd.pipe0.remaining = rem - len; + _dcd.remaining_ctrl -= len; + + _dcd.pipe0.buf = NULL; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(0, TUSB_DIR_OUT), + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } + return; + } + + /* When CSRL0 is zero, it means that completion of sending a any length packet + * or receiving a zero length packet. */ + if (req != REQUEST_TYPE_INVALID && !tu_edpt_dir(req)) { + /* STATUS IN */ + if (*(const uint16_t*)(uintptr_t)&_dcd.setup_packet == 0x0500) { + /* The address must be changed on completion of the control transfer. */ + MXC_USBHS->faddr = (uint8_t)_dcd.setup_packet.wValue; + } + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(0, TUSB_DIR_IN), + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + return; + } + if (_dcd.pipe0.buf) { + /* DATA IN */ + _dcd.pipe0.buf = NULL; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(0, TUSB_DIR_IN), + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } +} + +static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) +{ + bool completed; + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned epnum = tu_edpt_number(ep_addr); + + MXC_USBHS->index = epnum; + + if (dir_in) { + if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_SENTSTALL) { + MXC_USBHS->incsrl &= ~(MXC_F_USBHS_INCSRL_SENTSTALL | MXC_F_USBHS_INCSRL_UNDERRUN); + return; + } + completed = handle_xfer_in(ep_addr); + } else { + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_SENTSTALL) { + MXC_USBHS->outcsrl &= ~(MXC_F_USBHS_OUTCSRL_SENTSTALL | MXC_F_USBHS_OUTCSRL_OVERRUN); + return; + } + completed = handle_xfer_out(ep_addr); + } + + if (completed) { + pipe_state_t *pipe = &_dcd.pipe[dir_in][tu_edpt_number(ep_addr) - 1]; + dcd_event_xfer_complete(rhport, ep_addr, + pipe->length - pipe->remaining, + XFER_RESULT_SUCCESS, true); + } +} + +static void process_bus_reset(uint8_t rhport) +{ + (void)rhport; + TU_LOG0("------Bus Reset\r\n"); + /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), + * a control transfer state is SETUP or STATUS stage. */ + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + _dcd.status_out = 0; + /* When pipe0.buf has not NULL, DATA stage works in progress. */ + _dcd.pipe0.buf = NULL; + + MXC_USBHS->intrinen = 1; /* Enable only EP0 */ + MXC_USBHS->introuten = 0; + + + /* Clear FIFO settings */ + for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { + MXC_USBHS->index = i; + if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { + /* Per musbhsfc_pg, only flush FIFO if IN packet loaded */ + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_FLUSHFIFO; + } + + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { + /* Per musbhsfc_pg, only flush FIFO if OUT packet is ready */ + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_FLUSHFIFO; + } + } + dcd_event_bus_reset(0, (MXC_USBHS->power & MXC_F_USBHS_POWER_HS_MODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); +} + +/*------------------------------------------------------------------ + * Device API + *------------------------------------------------------------------*/ + +void dcd_init(uint8_t rhport) +{ + (void)rhport; + MXC_USBHS->intrusben |= MXC_F_USBHS_INTRUSBEN_SUSPEND_INT_EN; + + //Interrupt for VBUS disconnect + MXC_USBHS->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS; + + NVIC_ClearPendingIRQ(USB_IRQn); + dcd_edpt_close_all(rhport); + + //Unsuspend the MAC + MXC_USBHS->mxm_suspend = 0; + + /* Configure PHY */ + MXC_USBHS->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11); + MXC_USBHS->m31_phy_xcfgi_63_32 = 0; + MXC_USBHS->m31_phy_xcfgi_95_64 = 0x1 << (72-64); + MXC_USBHS->m31_phy_xcfgi_127_96 = 0; + + +#ifdef USBHS_M31_CLOCK_RECOVERY + MXC_USBHS->m31_phy_noncry_rstb = 1; + MXC_USBHS->m31_phy_noncry_en = 1; + MXC_USBHS->m31_phy_outclksel = 0; + MXC_USBHS->m31_phy_coreclkin = 0; + MXC_USBHS->m31_phy_xtlsel = 2; /* Select 25 MHz clock */ +#else + /* Use this option to feed the PHY a 30 MHz clock, which is them used as a PLL reference */ + /* As it depends on the system core clock, this should probably be done at the SYS level */ + MXC_USBHS->m31_phy_noncry_rstb = 0; + MXC_USBHS->m31_phy_noncry_en = 0; + MXC_USBHS->m31_phy_outclksel = 1; + MXC_USBHS->m31_phy_coreclkin = 1; + MXC_USBHS->m31_phy_xtlsel = 3; /* Select 30 MHz clock */ +#endif + MXC_USBHS->m31_phy_pll_en = 1; + MXC_USBHS->m31_phy_oscouten = 1; + + /* Reset PHY */ + MXC_USBHS->m31_phy_ponrst = 0; + MXC_USBHS->m31_phy_ponrst = 1; + + dcd_connect(rhport); +} + +void dcd_int_enable(uint8_t rhport) +{ + (void)rhport; + NVIC_EnableIRQ(USB_IRQn); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void)rhport; + NVIC_DisableIRQ(USB_IRQn); +} + +// Receive Set Address request, mcu port must also include status IN response +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + (void)dev_addr; + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; + _dcd.pipe0.remaining = 0; + /* Clear RX FIFO to return ACK. */ + MXC_USBHS->index = 0; + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY | MXC_F_USBHS_CSR0_DATA_END; +} + +// Wake up host +void dcd_remote_wakeup(uint8_t rhport) +{ + (void)rhport; + MXC_USBHS->power |= MXC_F_USBHS_POWER_RESUME; + +#if CFG_TUSB_OS != OPT_OS_NONE + osal_task_delay(10); +#else + MXC_Delay(MXC_DELAY_MSEC(10)); +#endif + + MXC_USBHS->power &= ~MXC_F_USBHS_POWER_RESUME; +} + +// Connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void)rhport; + MXC_USBHS->power |= TUD_OPT_HIGH_SPEED ? MXC_F_USBHS_POWER_HS_ENABLE : 0; + MXC_USBHS->power |= MXC_F_USBHS_POWER_SOFTCONN; +} + +// Disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void)rhport; + MXC_USBHS->power &= ~MXC_F_USBHS_POWER_SOFTCONN; +} + +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +// Configure endpoint's registers according to descriptor +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) +{ + (void) rhport; + + const unsigned ep_addr = ep_desc->bEndpointAddress; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned xfer = ep_desc->bmAttributes.xfer; + const unsigned mps = tu_edpt_packet_size(ep_desc); + + TU_ASSERT(epn < TUP_DCD_ENDPOINT_MAX); + + pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; + pipe->buf = NULL; + pipe->length = 0; + pipe->remaining = 0; + + MXC_USBHS->index = epn; + + if (dir_in) { + MXC_USBHS->inmaxp = mps; + MXC_USBHS->incsru = (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE) | ((xfer == TUSB_XFER_ISOCHRONOUS) ? MXC_F_USBHS_INCSRU_ISO : 0); + if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; + } else { + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; + } + MXC_USBHS->intrinen |= TU_BIT(epn); + } else { + MXC_USBHS->outmaxp = mps; + MXC_USBHS->outcsru = (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS) | ((xfer == TUSB_XFER_ISOCHRONOUS) ? MXC_F_USBHS_OUTCSRU_ISO : 0); + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; + } else { + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; + } + MXC_USBHS->introuten |= TU_BIT(epn); + } + + return true; +} + +void dcd_edpt_close_all(uint8_t rhport) +{ + (void) rhport; + + MXC_SYS_Crit_Enter(); + MXC_USBHS->intrinen = 1; /* Enable only EP0 */ + MXC_USBHS->introuten = 0; + + for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { + MXC_USBHS->index = i; + MXC_USBHS->inmaxp = 0; + MXC_USBHS->incsru = MXC_F_USBHS_INCSRU_DPKTBUFDIS; + + if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; + } else { + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; + } + + MXC_USBHS->outmaxp = 0; + MXC_USBHS->outcsru = MXC_F_USBHS_OUTCSRU_DPKTBUFDIS; + + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; + } else { + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; + } + } + MXC_SYS_Crit_Exit(); +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + unsigned const epn = tu_edpt_number(ep_addr); + unsigned const dir_in = tu_edpt_dir(ep_addr); + + MXC_SYS_Crit_Enter(); + MXC_USBHS->index = epn; + if (dir_in) { + MXC_USBHS->intrinen &= ~TU_BIT(epn); + MXC_USBHS->inmaxp = 0; + MXC_USBHS->incsru = MXC_F_USBHS_INCSRU_DPKTBUFDIS; + if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; + } else { + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; + } + } else { + MXC_USBHS->introuten &= ~TU_BIT(epn); + MXC_USBHS->outmaxp = 0; + MXC_USBHS->outcsru = MXC_F_USBHS_OUTCSRU_DPKTBUFDIS; + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; + } else { + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; + } + } + MXC_SYS_Crit_Exit(); +} + +// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + (void)rhport; + bool ret; + unsigned const epnum = tu_edpt_number(ep_addr); + MXC_SYS_Crit_Enter(); + if (epnum) { + _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); + ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); + } else + ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); + MXC_SYS_Crit_Exit(); + return ret; +} + +// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void)rhport; + bool ret; + unsigned const epnum = tu_edpt_number(ep_addr); + TU_ASSERT(epnum); + MXC_SYS_Crit_Enter(); + _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] |= TU_BIT(epnum - 1); + ret = edpt_n_xfer(rhport, ep_addr, (uint8_t*)ff, total_bytes); + MXC_SYS_Crit_Exit(); + return ret; +} + +// Stall endpoint +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + unsigned const epn = tu_edpt_number(ep_addr); + MXC_SYS_Crit_Enter(); + MXC_USBHS->index = epn; + if (0 == epn) { + if (!ep_addr) { /* Ignore EP80 */ + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + _dcd.pipe0.buf = NULL; + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SEND_STALL; + } + } else { + if (tu_edpt_dir(ep_addr)) { /* IN */ + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_SENDSTALL; + } else { /* OUT */ + TU_ASSERT(!(MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY),); + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_SENDSTALL; + } + } + MXC_SYS_Crit_Exit(); +} + +// clear stall, data toggle is also reset to DATA0 +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + unsigned const epn = tu_edpt_number(ep_addr); + MXC_SYS_Crit_Enter(); + MXC_USBHS->index = epn; + if (tu_edpt_dir(ep_addr)) { /* IN */ + /* IN endpoint */ + if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { + /* Per musbhsfc_pg, only flush FIFO if IN packet loaded */ + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; + } else { + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; + } + } else { /* OUT */ + /* Otherwise, must be OUT endpoint */ + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { + /* Per musbhsfc_pg, only flush FIFO if OUT packet is ready */ + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; + } else { + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; + } + } + MXC_SYS_Crit_Exit(); +} + +/*------------------------------------------------------------------- + * ISR + *-------------------------------------------------------------------*/ +void dcd_int_handler(uint8_t rhport) +{ + uint_fast8_t is, txis, rxis; + uint32_t mxm_int, mxm_int_en, mxm_is; + uint32_t saved_index; + + /* Save current index register */ + saved_index = MXC_USBHS->index; + + is = MXC_USBHS->intrusb; /* read and clear interrupt status */ + txis = MXC_USBHS->intrin; /* read and clear interrupt status */ + rxis = MXC_USBHS->introut; /* read and clear interrupt status */ + + /* These USB interrupt flags are W1C. */ + /* Order of volatile accesses must be separated for IAR */ + mxm_int = MXC_USBHS->mxm_int; + mxm_int_en = MXC_USBHS->mxm_int_en; + mxm_is = mxm_int & mxm_int_en; + MXC_USBHS->mxm_int = mxm_is; + + is &= MXC_USBHS->intrusben; /* Clear disabled interrupts */ + + if (mxm_is & MXC_F_USBHS_MXM_INT_NOVBUS) { + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); + } + if (is & MXC_F_USBHS_INTRUSB_SOF_INT) { + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } + if (is & MXC_F_USBHS_INTRUSB_RESET_INT) { + process_bus_reset(rhport); + } + if (is & MXC_F_USBHS_INTRUSB_RESUME_INT) { + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); + } + if (is & MXC_F_USBHS_INTRUSB_SUSPEND_INT) { + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + + txis &= MXC_USBHS->intrinen; /* Clear disabled interrupts */ + if (txis & MXC_F_USBHS_INTRIN_EP0_IN_INT) { + process_ep0(rhport); + txis &= ~TU_BIT(0); + } + while (txis) { + unsigned const num = __builtin_ctz(txis); + process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN)); + txis &= ~TU_BIT(num); + } + rxis &= MXC_USBHS->introuten; /* Clear disabled interrupts */ + while (rxis) { + unsigned const num = __builtin_ctz(rxis); + process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT)); + rxis &= ~TU_BIT(num); + } + + /* Restore register index before exiting ISR */ + MXC_USBHS->index = saved_index; +} + +#endif diff --git a/src/tusb_option.h b/src/tusb_option.h index db8b94580..18f78b49c 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -188,6 +188,9 @@ #define OPT_MCU_MCXN9 2300 ///< NXP MCX N9 Series #define OPT_MCU_MCXA15 2301 ///< NXP MCX A15 Series +// Analog Devices +#define OPT_MCU_MAX32690 2400 ///< ADI MAX32690 + // Check if configured MCU is one of listed // Apply _TU_CHECK_MCU with || as separator to list of input #define _TU_CHECK_MCU(_m) (CFG_TUSB_MCU == _m) diff --git a/tools/get_deps.py b/tools/get_deps.py index 50cc5c893..e05cc4d76 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -24,6 +24,9 @@ deps_optional = { 'hw/mcu/allwinner': ['https://github.com/hathach/allwinner_driver.git', '8e5e89e8e132c0fd90e72d5422e5d3d68232b756', 'fc100s'], + 'hw/mcu/analog/max32' : ['https://github.com/analogdevicesinc/msdk.git', + 'b20b398d3e5e2007594e54a74ba3d2a2e50ddd75', + 'max32690'], 'hw/mcu/bridgetek/ft9xx/ft90x-sdk': ['https://github.com/BRTSG-FOSS/ft90x-sdk.git', '91060164afe239fcb394122e8bf9eb24d3194eb1', 'brtmm90x'], -- cgit v1.3.1 From 0b82af61f3ca7f6b708399c49519fb109ab33abb Mon Sep 17 00:00:00 2001 From: Brent Kowal Date: Mon, 1 Jul 2024 16:31:17 -0400 Subject: AD-APARD32690-SL Support and Cleanup - Added BSP for AD-APARD32690-SL board (apard32690) - Ran clang-formatting on previously committed code - Removed LOG messages from dcd_max32.c --- hw/bsp/max32690/boards/apard32690/board.cmake | 1 + hw/bsp/max32690/boards/apard32690/board.h | 56 +++++ hw/bsp/max32690/boards/apard32690/board.mk | 1 + hw/bsp/max32690/boards/max32690evkit/board.h | 22 +- hw/bsp/max32690/family.c | 32 +-- src/portable/analog/max32/dcd_max32.c | 339 ++++++++++++-------------- 6 files changed, 239 insertions(+), 212 deletions(-) create mode 100644 hw/bsp/max32690/boards/apard32690/board.cmake create mode 100644 hw/bsp/max32690/boards/apard32690/board.h create mode 100644 hw/bsp/max32690/boards/apard32690/board.mk diff --git a/hw/bsp/max32690/boards/apard32690/board.cmake b/hw/bsp/max32690/boards/apard32690/board.cmake new file mode 100644 index 000000000..9dc6962eb --- /dev/null +++ b/hw/bsp/max32690/boards/apard32690/board.cmake @@ -0,0 +1 @@ +# Nothing to be done at the board level diff --git a/hw/bsp/max32690/boards/apard32690/board.h b/hw/bsp/max32690/boards/apard32690/board.h new file mode 100644 index 000000000..f94097ca9 --- /dev/null +++ b/hw/bsp/max32690/boards/apard32690/board.h @@ -0,0 +1,56 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#include "gpio.h" +#include "mxc_sys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// LED +#define LED_PORT MXC_GPIO2 +#define LED_PIN MXC_GPIO_PIN_1 +#define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH +#define LED_STATE_ON 1 + +// Button +#define BUTTON_PORT MXC_GPIO1 +#define BUTTON_PIN MXC_GPIO_PIN_27 +#define BUTTON_PULL MXC_GPIO_PAD_NONE +#define BUTTON_STATE_ACTIVE 1 + +// UART Enable for UART on ARM SWD Connector +#define UART_NUM 0 + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/max32690/boards/apard32690/board.mk b/hw/bsp/max32690/boards/apard32690/board.mk new file mode 100644 index 000000000..a813a5327 --- /dev/null +++ b/hw/bsp/max32690/boards/apard32690/board.mk @@ -0,0 +1 @@ +# No specific build requirements for the board. diff --git a/hw/bsp/max32690/boards/max32690evkit/board.h b/hw/bsp/max32690/boards/max32690evkit/board.h index f5a904702..05d60f220 100644 --- a/hw/bsp/max32690/boards/max32690evkit/board.h +++ b/hw/bsp/max32690/boards/max32690evkit/board.h @@ -31,26 +31,26 @@ #include "mxc_sys.h" #ifdef __cplusplus - extern "C" { +extern "C" { #endif // LED -#define LED_PORT MXC_GPIO0 -#define LED_PIN MXC_GPIO_PIN_14 -#define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH -#define LED_STATE_ON 0 +#define LED_PORT MXC_GPIO0 +#define LED_PIN MXC_GPIO_PIN_14 +#define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH +#define LED_STATE_ON 0 // Button -#define BUTTON_PORT MXC_GPIO4 -#define BUTTON_PIN MXC_GPIO_PIN_0 -#define BUTTON_PULL MXC_GPIO_PAD_PULL_UP -#define BUTTON_STATE_ACTIVE 0 +#define BUTTON_PORT MXC_GPIO4 +#define BUTTON_PIN MXC_GPIO_PIN_0 +#define BUTTON_PULL MXC_GPIO_PAD_PULL_UP +#define BUTTON_STATE_ACTIVE 0 // UART Enable for EvKit's Integrated FTDI Adapter. Pin Mux handled by the HAL -#define UART_NUM 2 +#define UART_NUM 2 #ifdef __cplusplus - } +} #endif #endif /* BOARD_H_ */ diff --git a/hw/bsp/max32690/family.c b/hw/bsp/max32690/family.c index f443bc575..acd6e2593 100644 --- a/hw/bsp/max32690/family.c +++ b/hw/bsp/max32690/family.c @@ -24,12 +24,12 @@ * This file is part of the TinyUSB stack. */ -#include "bsp/board_api.h" #include "board.h" -#include "mxc_device.h" +#include "bsp/board_api.h" +#include "gpio.h" #include "mcr_regs.h" +#include "mxc_device.h" #include "uart.h" -#include "gpio.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler @@ -49,7 +49,7 @@ void board_init(void) { SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif mxc_gpio_cfg_t gpioConfig; @@ -87,10 +87,10 @@ void board_init(void) { //--------------------------------------------------------------------+ void board_led_write(bool state) { - #if LED_STATE_ON - state = !state; - #endif - if(state) { +#if LED_STATE_ON + state = !state; +#endif + if (state) { MXC_GPIO_OutClr(LED_PORT, LED_PIN); } else { MXC_GPIO_OutSet(LED_PORT, LED_PIN); @@ -103,9 +103,9 @@ uint32_t board_button_read(void) { } size_t board_get_unique_id(uint8_t id[], size_t max_len) { - uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN]; //USN Buffer - /* All other 2nd parameter is optional checkum buffer */ - MXC_SYS_GetUSN(hw_id, NULL); + uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN];//USN Buffer + /* All other 2nd parameter is optional checkum buffer */ + MXC_SYS_GetUSN(hw_id, NULL); size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN); memcpy(id, hw_id, act_len); @@ -116,11 +116,11 @@ int board_uart_read(uint8_t *buf, int len) { int uart_val; int act_len = 0; - while( act_len < len ) { - if((uart_val = MXC_UART_ReadCharacterRaw(ConsoleUart)) == E_UNDERFLOW) { + while (act_len < len) { + if ((uart_val = MXC_UART_ReadCharacterRaw(ConsoleUart)) == E_UNDERFLOW) { break; } else { - *buf++ = (uint8_t)uart_val; + *buf++ = (uint8_t) uart_val; act_len++; } } @@ -129,8 +129,8 @@ int board_uart_read(uint8_t *buf, int len) { int board_uart_write(void const *buf, int len) { int act_len = 0; - const uint8_t* ch_ptr = (const uint8_t*)buf; - while(act_len < len){ + const uint8_t *ch_ptr = (const uint8_t *) buf; + while (act_len < len) { MXC_UART_WriteCharacter(ConsoleUart, *ch_ptr++); act_len++; } diff --git a/src/portable/analog/max32/dcd_max32.c b/src/portable/analog/max32/dcd_max32.c index 150d476fa..b3370ddd1 100644 --- a/src/portable/analog/max32/dcd_max32.c +++ b/src/portable/analog/max32/dcd_max32.c @@ -29,49 +29,48 @@ #if CFG_TUD_ENABLED && TU_CHECK_MCU(OPT_MCU_MAX32690) -#if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) + #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) /* GCC warns that an address may be unaligned, even though * the target CPU has the capability for unaligned memory access. */ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); -#endif + #endif -#include "device/dcd.h" + #include "device/dcd.h" -#include "mxc_delay.h" -#include "mxc_device.h" -#include "mxc_sys.h" -#include "nvic_table.h" -#include "usbhs_regs.h" + #include "mxc_delay.h" + #include "mxc_device.h" + #include "mxc_sys.h" + #include "nvic_table.h" + #include "usbhs_regs.h" -#define USBHS_M31_CLOCK_RECOVERY + #define USBHS_M31_CLOCK_RECOVERY -/*------------------------------------------------------------------ + /*------------------------------------------------------------------ * MACRO TYPEDEF CONSTANT ENUM DECLARATION *------------------------------------------------------------------*/ -#define REQUEST_TYPE_INVALID (0xFFu) + #define REQUEST_TYPE_INVALID (0xFFu) typedef union { - uint8_t u8; - uint16_t u16; - uint32_t u32; + uint8_t u8; + uint16_t u16; + uint32_t u32; } hw_fifo_t; -typedef struct TU_ATTR_PACKED -{ - void *buf; /* the start address of a transfer data buffer */ - uint16_t length; /* the number of bytes in the buffer */ - uint16_t remaining; /* the number of bytes remaining in the buffer */ +typedef struct TU_ATTR_PACKED { + void *buf; /* the start address of a transfer data buffer */ + uint16_t length; /* the number of bytes in the buffer */ + uint16_t remaining; /* the number of bytes remaining in the buffer */ } pipe_state_t; typedef struct { tusb_control_request_t setup_packet; - uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ - int8_t status_out; + uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ + int8_t status_out; pipe_state_t pipe0; - pipe_state_t pipe[2][TUP_DCD_ENDPOINT_MAX - 1]; /* pipe[direction][endpoint number - 1] */ - uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ + pipe_state_t pipe[2][TUP_DCD_ENDPOINT_MAX - 1]; /* pipe[direction][endpoint number - 1] */ + uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ } dcd_data_t; /*------------------------------------------------------------------ @@ -80,63 +79,59 @@ typedef struct static dcd_data_t _dcd; -static volatile void* edpt_get_fifo_ptr(unsigned epnum) -{ - volatile uint32_t *ptr; +static volatile void *edpt_get_fifo_ptr(unsigned epnum) { + volatile uint32_t *ptr; - ptr = &MXC_USBHS->fifo0; - ptr += epnum; /* Pointer math: multiplies ep by sizeof(uint32_t) */ + ptr = &MXC_USBHS->fifo0; + ptr += epnum; /* Pointer math: multiplies ep by sizeof(uint32_t) */ - return (volatile void *)ptr; + return (volatile void *) ptr; } -static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) -{ - volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; - uintptr_t addr = (uintptr_t)buf; +static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { + volatile hw_fifo_t *reg = (volatile hw_fifo_t *) fifo; + uintptr_t addr = (uintptr_t) buf; while (len >= 4) { - reg->u32 = *(uint32_t const *)addr; + reg->u32 = *(uint32_t const *) addr; addr += 4; - len -= 4; + len -= 4; } if (len >= 2) { - reg->u16 = *(uint16_t const *)addr; + reg->u16 = *(uint16_t const *) addr; addr += 2; - len -= 2; + len -= 2; } if (len) { - reg->u8 = *(uint8_t const *)addr; + reg->u8 = *(uint8_t const *) addr; } } -static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) -{ - volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; - uintptr_t addr = (uintptr_t)buf; +static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) { + volatile hw_fifo_t *reg = (volatile hw_fifo_t *) fifo; + uintptr_t addr = (uintptr_t) buf; while (len >= 4) { - *(uint32_t *)addr = reg->u32; + *(uint32_t *) addr = reg->u32; addr += 4; - len -= 4; + len -= 4; } if (len >= 2) { - *(uint16_t *)addr = reg->u16; + *(uint16_t *) addr = reg->u16; addr += 2; - len -= 2; + len -= 2; } if (len) { - *(uint8_t *)addr = reg->u8; + *(uint8_t *) addr = reg->u8; } } -static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir) -{ +static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir) { static const struct { void (*tu_fifo_get_info)(tu_fifo_t *f, tu_fifo_buffer_info_t *info); void (*tu_fifo_advance)(tu_fifo_t *f, uint16_t n); void (*pipe_read_write)(void *buf, volatile void *fifo, unsigned len); } ops[] = { - /* OUT */ {tu_fifo_get_write_info,tu_fifo_advance_write_pointer,pipe_read_packet}, - /* IN */ {tu_fifo_get_read_info, tu_fifo_advance_read_pointer, pipe_write_packet}, + /* OUT */ {tu_fifo_get_write_info, tu_fifo_advance_write_pointer, pipe_read_packet}, + /* IN */ {tu_fifo_get_read_info, tu_fifo_advance_read_pointer, pipe_write_packet}, }; tu_fifo_buffer_info_t info; ops[dir].tu_fifo_get_info(f, &info); @@ -152,19 +147,18 @@ static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigne ops[dir].tu_fifo_advance(f, total_len - rem); } -static void process_setup_packet(uint8_t rhport) -{ - uint32_t *p = (void*)&_dcd.setup_packet; - p[0] = MXC_USBHS->fifo0; - p[1] = MXC_USBHS->fifo0; +static void process_setup_packet(uint8_t rhport) { + uint32_t *p = (void *) &_dcd.setup_packet; + p[0] = MXC_USBHS->fifo0; + p[1] = MXC_USBHS->fifo0; - _dcd.pipe0.buf = NULL; - _dcd.pipe0.length = 0; + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; - dcd_event_setup_received(rhport, (const uint8_t*)(uintptr_t)&_dcd.setup_packet, true); + dcd_event_setup_received(rhport, (const uint8_t *) (uintptr_t) &_dcd.setup_packet, true); - const unsigned len = _dcd.setup_packet.wLength; - _dcd.remaining_ctrl = len; + const unsigned len = _dcd.setup_packet.wLength; + _dcd.remaining_ctrl = len; const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); /* Clear RX FIFO and reverse the transaction direction */ if (len && dir_in) { @@ -173,12 +167,11 @@ static void process_setup_packet(uint8_t rhport) } } -static bool handle_xfer_in(uint_fast8_t ep_addr) -{ +static bool handle_xfer_in(uint_fast8_t ep_addr) { unsigned epnum = tu_edpt_number(ep_addr); unsigned epnum_minus1 = epnum - 1; - pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; - const unsigned rem = pipe->remaining; + pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + const unsigned rem = pipe->remaining; //This function should not be for ep0 TU_ASSERT(epnum); @@ -191,28 +184,26 @@ static bool handle_xfer_in(uint_fast8_t ep_addr) MXC_USBHS->index = epnum; const unsigned mps = MXC_USBHS->inmaxp; const unsigned len = TU_MIN(mps, rem); - void *buf = pipe->buf; - volatile void* fifo_ptr = edpt_get_fifo_ptr(epnum); - // TU_LOG1(" %p mps %d len %d rem %d\r\n", buf, mps, len, rem); + void *buf = pipe->buf; + volatile void *fifo_ptr = edpt_get_fifo_ptr(epnum); if (len) { if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_IN); } else { - pipe_write_packet(buf,fifo_ptr, len); - pipe->buf = buf + len; + pipe_write_packet(buf, fifo_ptr, len); + pipe->buf = buf + len; } pipe->remaining = rem - len; } - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_INPKTRDY; //TODO: Verify a | isnt needed + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_INPKTRDY;//TODO: Verify a | isnt needed return false; } -static bool handle_xfer_out(uint_fast8_t ep_addr) -{ +static bool handle_xfer_out(uint_fast8_t ep_addr) { unsigned epnum = tu_edpt_number(ep_addr); unsigned epnum_minus1 = epnum - 1; - pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; //This function should not be for ep0 TU_ASSERT(epnum); @@ -225,14 +216,14 @@ static bool handle_xfer_out(uint_fast8_t ep_addr) const unsigned rem = pipe->remaining; const unsigned vld = MXC_USBHS->outcount; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); - void *buf = pipe->buf; - volatile void* fifo_ptr = edpt_get_fifo_ptr(epnum); + void *buf = pipe->buf; + volatile void *fifo_ptr = edpt_get_fifo_ptr(epnum); if (len) { if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { - pipe_read_write_packet_ff(buf,fifo_ptr, len, TUSB_DIR_OUT); + pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_OUT); } else { pipe_read_packet(buf, fifo_ptr, len); - pipe->buf = buf + len; + pipe->buf = buf + len; } pipe->remaining = rem - len; } @@ -240,37 +231,35 @@ static bool handle_xfer_out(uint_fast8_t ep_addr) pipe->buf = NULL; return NULL != buf; } - MXC_USBHS->outcsrl = 0; /* Clear RXRDY bit */ //TODO: Verify just setting to 0 is ok + MXC_USBHS->outcsrl = 0; /* Clear RXRDY bit *///TODO: Verify just setting to 0 is ok return false; } -static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) -{ - (void)rhport; +static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { + (void) rhport; - unsigned epnum = tu_edpt_number(ep_addr); + unsigned epnum = tu_edpt_number(ep_addr); unsigned epnum_minus1 = epnum - 1; - unsigned dir_in = tu_edpt_dir(ep_addr); + unsigned dir_in = tu_edpt_dir(ep_addr); pipe_state_t *pipe = &_dcd.pipe[dir_in][epnum_minus1]; - pipe->buf = buffer; - pipe->length = total_bytes; - pipe->remaining = total_bytes; + pipe->buf = buffer; + pipe->length = total_bytes; + pipe->remaining = total_bytes; if (dir_in) { handle_xfer_in(ep_addr); } else { MXC_USBHS->index = epnum; - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY){ - MXC_USBHS->outcsrl = 0; //TODO: Verify just setting to 0 is ok + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { + MXC_USBHS->outcsrl = 0;//TODO: Verify just setting to 0 is ok } } return true; } -static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) -{ - (void)rhport; +static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { + (void) rhport; TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ const unsigned req = _dcd.setup_packet.bmRequestType; @@ -299,15 +288,15 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ TU_ASSERT(total_bytes <= _dcd.remaining_ctrl); const unsigned rem = _dcd.remaining_ctrl; const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes); - volatile void* fifo_ptr = edpt_get_fifo_ptr(0); + volatile void *fifo_ptr = edpt_get_fifo_ptr(0); if (dir_in) { pipe_write_packet(buffer, fifo_ptr, len); - _dcd.pipe0.buf = buffer + len; - _dcd.pipe0.length = len; + _dcd.pipe0.buf = buffer + len; + _dcd.pipe0.length = len; _dcd.pipe0.remaining = 0; - _dcd.remaining_ctrl = rem - len; + _dcd.remaining_ctrl = rem - len; if ((len < 64) || (rem == len)) { _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ _dcd.status_out = 1; @@ -317,14 +306,14 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_INPKTRDY; /* Flush TX FIFO to return ACK. */ } } else { - _dcd.pipe0.buf = buffer; - _dcd.pipe0.length = len; + _dcd.pipe0.buf = buffer; + _dcd.pipe0.length = len; _dcd.pipe0.remaining = len; MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY; /* Clear RX FIFO to return ACK. */ } } else if (dir_in) { _dcd.pipe0.buf = NULL; - _dcd.pipe0.length = 0; + _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO and reverse the transaction direction */ MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY | MXC_F_USBHS_CSR0_DATA_END; @@ -332,8 +321,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ return true; } -static void process_ep0(uint8_t rhport) -{ +static void process_ep0(uint8_t rhport) { MXC_USBHS->index = 0; uint_fast8_t csrl = MXC_USBHS->csr0; @@ -364,7 +352,7 @@ static void process_ep0(uint8_t rhport) /* Received SETUP or DATA OUT packet */ if (req == REQUEST_TYPE_INVALID) { /* SETUP */ - TU_ASSERT(sizeof(tusb_control_request_t) == MXC_USBHS->count0,); + TU_ASSERT(sizeof(tusb_control_request_t) == MXC_USBHS->count0, ); process_setup_packet(rhport); return; } @@ -373,7 +361,7 @@ static void process_ep0(uint8_t rhport) const unsigned vld = MXC_USBHS->count0; const unsigned rem = _dcd.pipe0.remaining; const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); - volatile void* fifo_ptr = edpt_get_fifo_ptr(0); + volatile void *fifo_ptr = edpt_get_fifo_ptr(0); pipe_read_packet(_dcd.pipe0.buf, fifo_ptr, len); _dcd.pipe0.remaining = rem - len; @@ -392,9 +380,9 @@ static void process_ep0(uint8_t rhport) * or receiving a zero length packet. */ if (req != REQUEST_TYPE_INVALID && !tu_edpt_dir(req)) { /* STATUS IN */ - if (*(const uint16_t*)(uintptr_t)&_dcd.setup_packet == 0x0500) { + if (*(const uint16_t *) (uintptr_t) &_dcd.setup_packet == 0x0500) { /* The address must be changed on completion of the control transfer. */ - MXC_USBHS->faddr = (uint8_t)_dcd.setup_packet.wValue; + MXC_USBHS->faddr = (uint8_t) _dcd.setup_packet.wValue; } _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; dcd_event_xfer_complete(rhport, @@ -413,11 +401,10 @@ static void process_ep0(uint8_t rhport) } } -static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) -{ +static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) { bool completed; - const unsigned dir_in = tu_edpt_dir(ep_addr); - const unsigned epnum = tu_edpt_number(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned epnum = tu_edpt_number(ep_addr); MXC_USBHS->index = epnum; @@ -443,10 +430,8 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) } } -static void process_bus_reset(uint8_t rhport) -{ - (void)rhport; - TU_LOG0("------Bus Reset\r\n"); +static void process_bus_reset(uint8_t rhport) { + (void) rhport; /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), * a control transfer state is SETUP or STATUS stage. */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; @@ -462,14 +447,14 @@ static void process_bus_reset(uint8_t rhport) for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { MXC_USBHS->index = i; if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { - /* Per musbhsfc_pg, only flush FIFO if IN packet loaded */ - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_FLUSHFIFO; - } + /* Per musbhsfc_pg, only flush FIFO if IN packet loaded */ + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_FLUSHFIFO; + } - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { - /* Per musbhsfc_pg, only flush FIFO if OUT packet is ready */ - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_FLUSHFIFO; - } + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { + /* Per musbhsfc_pg, only flush FIFO if OUT packet is ready */ + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_FLUSHFIFO; + } } dcd_event_bus_reset(0, (MXC_USBHS->power & MXC_F_USBHS_POWER_HS_MODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); } @@ -478,9 +463,8 @@ static void process_bus_reset(uint8_t rhport) * Device API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport) -{ - (void)rhport; +void dcd_init(uint8_t rhport) { + (void) rhport; MXC_USBHS->intrusben |= MXC_F_USBHS_INTRUSBEN_SUSPEND_INT_EN; //Interrupt for VBUS disconnect @@ -495,17 +479,17 @@ void dcd_init(uint8_t rhport) /* Configure PHY */ MXC_USBHS->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11); MXC_USBHS->m31_phy_xcfgi_63_32 = 0; - MXC_USBHS->m31_phy_xcfgi_95_64 = 0x1 << (72-64); + MXC_USBHS->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64); MXC_USBHS->m31_phy_xcfgi_127_96 = 0; -#ifdef USBHS_M31_CLOCK_RECOVERY + #ifdef USBHS_M31_CLOCK_RECOVERY MXC_USBHS->m31_phy_noncry_rstb = 1; MXC_USBHS->m31_phy_noncry_en = 1; MXC_USBHS->m31_phy_outclksel = 0; MXC_USBHS->m31_phy_coreclkin = 0; MXC_USBHS->m31_phy_xtlsel = 2; /* Select 25 MHz clock */ -#else + #else /* Use this option to feed the PHY a 30 MHz clock, which is them used as a PLL reference */ /* As it depends on the system core clock, this should probably be done at the SYS level */ MXC_USBHS->m31_phy_noncry_rstb = 0; @@ -513,7 +497,7 @@ void dcd_init(uint8_t rhport) MXC_USBHS->m31_phy_outclksel = 1; MXC_USBHS->m31_phy_coreclkin = 1; MXC_USBHS->m31_phy_xtlsel = 3; /* Select 30 MHz clock */ -#endif + #endif MXC_USBHS->m31_phy_pll_en = 1; MXC_USBHS->m31_phy_oscouten = 1; @@ -524,25 +508,22 @@ void dcd_init(uint8_t rhport) dcd_connect(rhport); } -void dcd_int_enable(uint8_t rhport) -{ - (void)rhport; +void dcd_int_enable(uint8_t rhport) { + (void) rhport; NVIC_EnableIRQ(USB_IRQn); } -void dcd_int_disable(uint8_t rhport) -{ - (void)rhport; +void dcd_int_disable(uint8_t rhport) { + (void) rhport; NVIC_DisableIRQ(USB_IRQn); } // Receive Set Address request, mcu port must also include status IN response -void dcd_set_address(uint8_t rhport, uint8_t dev_addr) -{ - (void)rhport; - (void)dev_addr; - _dcd.pipe0.buf = NULL; - _dcd.pipe0.length = 0; +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { + (void) rhport; + (void) dev_addr; + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO to return ACK. */ MXC_USBHS->index = 0; @@ -550,37 +531,33 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) } // Wake up host -void dcd_remote_wakeup(uint8_t rhport) -{ - (void)rhport; +void dcd_remote_wakeup(uint8_t rhport) { + (void) rhport; MXC_USBHS->power |= MXC_F_USBHS_POWER_RESUME; -#if CFG_TUSB_OS != OPT_OS_NONE + #if CFG_TUSB_OS != OPT_OS_NONE osal_task_delay(10); -#else + #else MXC_Delay(MXC_DELAY_MSEC(10)); -#endif + #endif MXC_USBHS->power &= ~MXC_F_USBHS_POWER_RESUME; } // Connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(uint8_t rhport) -{ - (void)rhport; +void dcd_connect(uint8_t rhport) { + (void) rhport; MXC_USBHS->power |= TUD_OPT_HIGH_SPEED ? MXC_F_USBHS_POWER_HS_ENABLE : 0; MXC_USBHS->power |= MXC_F_USBHS_POWER_SOFTCONN; } // Disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(uint8_t rhport) -{ - (void)rhport; +void dcd_disconnect(uint8_t rhport) { + (void) rhport; MXC_USBHS->power &= ~MXC_F_USBHS_POWER_SOFTCONN; } -void dcd_sof_enable(uint8_t rhport, bool en) -{ +void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; @@ -592,21 +569,20 @@ void dcd_sof_enable(uint8_t rhport, bool en) //--------------------------------------------------------------------+ // Configure endpoint's registers according to descriptor -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) -{ +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) { (void) rhport; const unsigned ep_addr = ep_desc->bEndpointAddress; - const unsigned epn = tu_edpt_number(ep_addr); - const unsigned dir_in = tu_edpt_dir(ep_addr); - const unsigned xfer = ep_desc->bmAttributes.xfer; - const unsigned mps = tu_edpt_packet_size(ep_desc); + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned xfer = ep_desc->bmAttributes.xfer; + const unsigned mps = tu_edpt_packet_size(ep_desc); TU_ASSERT(epn < TUP_DCD_ENDPOINT_MAX); pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; - pipe->buf = NULL; - pipe->length = 0; + pipe->buf = NULL; + pipe->length = 0; pipe->remaining = 0; MXC_USBHS->index = epn; @@ -634,8 +610,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) return true; } -void dcd_edpt_close_all(uint8_t rhport) -{ +void dcd_edpt_close_all(uint8_t rhport) { (void) rhport; MXC_SYS_Crit_Enter(); @@ -665,10 +640,9 @@ void dcd_edpt_close_all(uint8_t rhport) MXC_SYS_Crit_Exit(); } -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) -{ - (void)rhport; - unsigned const epn = tu_edpt_number(ep_addr); +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + unsigned const epn = tu_edpt_number(ep_addr); unsigned const dir_in = tu_edpt_dir(ep_addr); MXC_SYS_Crit_Enter(); @@ -683,7 +657,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; } } else { - MXC_USBHS->introuten &= ~TU_BIT(epn); + MXC_USBHS->introuten &= ~TU_BIT(epn); MXC_USBHS->outmaxp = 0; MXC_USBHS->outcsru = MXC_F_USBHS_OUTCSRU_DPKTBUFDIS; if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { @@ -696,9 +670,8 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) } // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ - (void)rhport; +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { + (void) rhport; bool ret; unsigned const epnum = tu_edpt_number(ep_addr); MXC_SYS_Crit_Enter(); @@ -712,23 +685,21 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t } // Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c -bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) -{ - (void)rhport; +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) { + (void) rhport; bool ret; unsigned const epnum = tu_edpt_number(ep_addr); TU_ASSERT(epnum); MXC_SYS_Crit_Enter(); _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] |= TU_BIT(epnum - 1); - ret = edpt_n_xfer(rhport, ep_addr, (uint8_t*)ff, total_bytes); + ret = edpt_n_xfer(rhport, ep_addr, (uint8_t *) ff, total_bytes); MXC_SYS_Crit_Exit(); return ret; } // Stall endpoint -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) -{ - (void)rhport; +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; unsigned const epn = tu_edpt_number(ep_addr); MXC_SYS_Crit_Enter(); MXC_USBHS->index = epn; @@ -742,7 +713,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) if (tu_edpt_dir(ep_addr)) { /* IN */ MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_SENDSTALL; } else { /* OUT */ - TU_ASSERT(!(MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY),); + TU_ASSERT(!(MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY), ); MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_SENDSTALL; } } @@ -750,9 +721,8 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) } // clear stall, data toggle is also reset to DATA0 -void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) -{ - (void)rhport; +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; unsigned const epn = tu_edpt_number(ep_addr); MXC_SYS_Crit_Enter(); MXC_USBHS->index = epn; @@ -779,8 +749,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) /*------------------------------------------------------------------- * ISR *-------------------------------------------------------------------*/ -void dcd_int_handler(uint8_t rhport) -{ +void dcd_int_handler(uint8_t rhport) { uint_fast8_t is, txis, rxis; uint32_t mxm_int, mxm_int_en, mxm_is; uint32_t saved_index; @@ -788,7 +757,7 @@ void dcd_int_handler(uint8_t rhport) /* Save current index register */ saved_index = MXC_USBHS->index; - is = MXC_USBHS->intrusb; /* read and clear interrupt status */ + is = MXC_USBHS->intrusb; /* read and clear interrupt status */ txis = MXC_USBHS->intrin; /* read and clear interrupt status */ rxis = MXC_USBHS->introut; /* read and clear interrupt status */ -- cgit v1.3.1 From 2353c4ffbaa50072d89008df7a06a7732c824018 Mon Sep 17 00:00:00 2001 From: Brent Kowal Date: Mon, 1 Jul 2024 17:31:38 -0400 Subject: Add MAX78002 Support -Added support for MAX78002, MAX78002EVKIT -Added provisions for remaining MAX32 USB parts --- examples/device/cdc_msc/src/usb_descriptors.c | 3 +- .../device/cdc_msc_freertos/src/usb_descriptors.c | 3 +- examples/device/cdc_uac2/src/usb_descriptors.c | 3 +- .../dynamic_configuration/src/usb_descriptors.c | 3 +- examples/device/midi_test/src/usb_descriptors.c | 3 +- examples/device/msc_dual_lun/src/usb_descriptors.c | 3 +- .../device/net_lwip_webserver/src/tusb_config.h | 2 +- .../net_lwip_webserver/src/usb_descriptors.c | 3 +- examples/device/uac2_headset/src/usb_descriptors.c | 3 +- .../device/webusb_serial/src/usb_descriptors.c | 3 +- hw/bsp/board_mcu.h | 9 ++ hw/bsp/max78002/FreeRTOSConfig/FreeRTOSConfig.h | 149 +++++++++++++++++ hw/bsp/max78002/boards/max78002evkit/board.cmake | 1 + hw/bsp/max78002/boards/max78002evkit/board.h | 58 +++++++ hw/bsp/max78002/boards/max78002evkit/board.mk | 1 + hw/bsp/max78002/family.c | 158 ++++++++++++++++++ hw/bsp/max78002/family.cmake | 152 +++++++++++++++++ hw/bsp/max78002/family.mk | 104 ++++++++++++ hw/bsp/max78002/max78002.ld | 180 +++++++++++++++++++++ src/common/tusb_mcu.h | 3 +- src/portable/analog/max32/dcd_max32.c | 3 +- src/tusb_option.h | 3 + tools/get_deps.py | 2 +- 23 files changed, 839 insertions(+), 13 deletions(-) create mode 100644 hw/bsp/max78002/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/max78002/boards/max78002evkit/board.cmake create mode 100644 hw/bsp/max78002/boards/max78002evkit/board.h create mode 100644 hw/bsp/max78002/boards/max78002evkit/board.mk create mode 100644 hw/bsp/max78002/family.c create mode 100644 hw/bsp/max78002/family.cmake create mode 100644 hw/bsp/max78002/family.mk create mode 100644 hw/bsp/max78002/max78002.ld diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c index 1ca614f4e..fac7cce8f 100644 --- a/examples/device/cdc_msc/src/usb_descriptors.c +++ b/examples/device/cdc_msc/src/usb_descriptors.c @@ -125,7 +125,8 @@ enum { #define EPNUM_MSC_OUT 0x04 #define EPNUM_MSC_IN 0x85 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // MAX32 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 diff --git a/examples/device/cdc_msc_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_freertos/src/usb_descriptors.c index f563e80d3..917b73e10 100644 --- a/examples/device/cdc_msc_freertos/src/usb_descriptors.c +++ b/examples/device/cdc_msc_freertos/src/usb_descriptors.c @@ -106,7 +106,8 @@ enum #define EPNUM_MSC_OUT 0x04 #define EPNUM_MSC_IN 0x85 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // MAX32 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 diff --git a/examples/device/cdc_uac2/src/usb_descriptors.c b/examples/device/cdc_uac2/src/usb_descriptors.c index 43e8cf3d7..ab1a2ee83 100644 --- a/examples/device/cdc_uac2/src/usb_descriptors.c +++ b/examples/device/cdc_uac2/src/usb_descriptors.c @@ -117,7 +117,8 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_CDC_OUT 0x04 #define EPNUM_CDC_IN 0x85 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // MAX32 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_AUDIO_IN 0x01 diff --git a/examples/device/dynamic_configuration/src/usb_descriptors.c b/examples/device/dynamic_configuration/src/usb_descriptors.c index eebdd4f69..20f237155 100644 --- a/examples/device/dynamic_configuration/src/usb_descriptors.c +++ b/examples/device/dynamic_configuration/src/usb_descriptors.c @@ -158,7 +158,8 @@ enum #define EPNUM_1_MSC_OUT 0x01 #define EPNUM_1_MSC_IN 0x82 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // FT9XX doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_0_CDC_NOTIF 0x81 diff --git a/examples/device/midi_test/src/usb_descriptors.c b/examples/device/midi_test/src/usb_descriptors.c index 797b50ab2..41e6e1818 100644 --- a/examples/device/midi_test/src/usb_descriptors.c +++ b/examples/device/midi_test/src/usb_descriptors.c @@ -90,7 +90,8 @@ enum // On Bridgetek FT9xx endpoint numbers must be unique... #define EPNUM_MIDI_OUT 0x02 #define EPNUM_MIDI_IN 0x03 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // On MAX32 endpoint numbers must be unique... #define EPNUM_MIDI_OUT 0x02 #define EPNUM_MIDI_IN 0x03 diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c index e32466228..c55bab0d8 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -97,7 +97,8 @@ enum #define EPNUM_MSC_OUT 0x01 #define EPNUM_MSC_IN 0x82 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // MAX32 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_MSC_OUT 0x01 diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h index 2f641f33e..22082fc81 100644 --- a/examples/device/net_lwip_webserver/src/tusb_config.h +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -91,7 +91,7 @@ extern "C" { #define USE_ECM 1 #elif TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F1) #define USE_ECM 1 -#elif TU_CHECK_MCU(OPT_MCU_MAX32690) +#elif TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002) #define USE_ECM 1 #else #define USE_ECM 0 diff --git a/examples/device/net_lwip_webserver/src/usb_descriptors.c b/examples/device/net_lwip_webserver/src/usb_descriptors.c index ba30b869e..012e1bcd8 100644 --- a/examples/device/net_lwip_webserver/src/usb_descriptors.c +++ b/examples/device/net_lwip_webserver/src/usb_descriptors.c @@ -120,7 +120,8 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_NET_OUT 0x02 #define EPNUM_NET_IN 0x83 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // MAX32 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_NET_NOTIF 0x81 diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c index bfc8a4ab5..a042ad206 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -104,7 +104,8 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_AUDIO_OUT 0x02 #define EPNUM_AUDIO_INT 0x03 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // MAX32 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_AUDIO_IN 0x01 diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c index bcfbe590e..ae1051af6 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.c +++ b/examples/device/webusb_serial/src/usb_descriptors.c @@ -105,7 +105,8 @@ enum #define EPNUM_CDC_OUT 3 #define EPNUM_VENDOR_IN 4 #define EPNUM_VENDOR_OUT 5 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // MAX32 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_IN 2 diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index 436164c35..d3a33cf36 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -173,6 +173,15 @@ #elif CFG_TUSB_MCU == OPT_MCU_MAX32690 #include "max32690.h" +#elif CFG_TUSB_MCU == OPT_MCU_MAX32650 + #include "max32650.h" + +#elif CFG_TUSB_MCU == OPT_MCU_MAX32666 + #include "max32665.h" + +#elif CFG_TUSB_MCU == OPT_MCU_MAX78002 + #include "max78002.h" + #else #error "Missing MCU header" #endif diff --git a/hw/bsp/max78002/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/max78002/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..e5a76af85 --- /dev/null +++ b/hw/bsp/max78002/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "mxc_device.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS __NVIC_PRIO_BITS + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<vssel |= UART_VDDIO_BITS; //Set necessary bits to 3.3V + + //USB + MXC_MCR->ldoctrl |= MXC_F_MCR_LDOCTRL_0P9EN; + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { +#if LED_STATE_ON + state = !state; +#endif + if (state) { + MXC_GPIO_OutClr(LED_PORT, LED_PIN); + } else { + MXC_GPIO_OutSet(LED_PORT, LED_PIN); + } +} + +uint32_t board_button_read(void) { + uint32_t state = MXC_GPIO_InGet(BUTTON_PORT, BUTTON_PIN) ? 1 : 0; + return BUTTON_STATE_ACTIVE == state; +} + +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN];//USN Buffer + /* All other 2nd parameter is optional checkum buffer */ + MXC_SYS_GetUSN(hw_id, NULL); + + size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN); + memcpy(id, hw_id, act_len); + return act_len; +} + +int board_uart_read(uint8_t *buf, int len) { + int uart_val; + int act_len = 0; + + while (act_len < len) { + if ((uart_val = MXC_UART_ReadCharacterRaw(ConsoleUart)) == E_UNDERFLOW) { + break; + } else { + *buf++ = (uint8_t) uart_val; + act_len++; + } + } + return act_len; +} + +int board_uart_write(void const *buf, int len) { + int act_len = 0; + const uint8_t *ch_ptr = (const uint8_t *) buf; + while (act_len < len) { + MXC_UART_WriteCharacter(ConsoleUart, *ch_ptr++); + act_len++; + } + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; +} + +uint32_t board_millis(void) { + return system_ticks; +} +#endif + +void HardFault_Handler(void) { + __asm("BKPT #0\n"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) { +} diff --git a/hw/bsp/max78002/family.cmake b/hw/bsp/max78002/family.cmake new file mode 100644 index 000000000..43b172b9f --- /dev/null +++ b/hw/bsp/max78002/family.cmake @@ -0,0 +1,152 @@ +include_guard() + +set(MAX32_PERIPH ${TOP}/hw/mcu/analog/max32/Libraries/PeriphDrivers) +set(MAX32_CMSIS ${TOP}/hw/mcu/analog/max32/Libraries/CMSIS) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# Get the linker file from current location (family) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max78002.ld) +set(LD_FILE_Clang ${LD_FILE_GNU}) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(JLINK_DEVICE max78000) + +set(FAMILY_MCUS MAX78002 CACHE INTERNAL "") + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + TARGET=MAX78002 + TARGET_REV=0x4131 + MXC_ASSERT_ENABLE + MAX78002 + IAR_PRAGMAS=0 + CFG_TUSB_MCU=OPT_MCU_MAX78002 + BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + ) +endfunction() + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + # Startup & Linker script + set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX78002/Source/GCC/startup_max78002.S) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + #set(STARTUP_FILE_IAR ?) + + set(PERIPH_SRC ${MAX32_PERIPH}/Source) + add_library(${BOARD_TARGET} STATIC + ${MAX32_CMSIS}/Device/Maxim/MAX78002/Source/heap.c + ${MAX32_CMSIS}/Device/Maxim/MAX78002/Source/system_max78002.c + ${PERIPH_SRC}/SYS/mxc_assert.c + ${PERIPH_SRC}/SYS/mxc_delay.c + ${PERIPH_SRC}/SYS/mxc_lock.c + ${PERIPH_SRC}/SYS/nvic_table.c + ${PERIPH_SRC}/SYS/pins_ai87.c + ${PERIPH_SRC}/SYS/sys_ai87.c + ${PERIPH_SRC}/AES/aes_ai87.c + ${PERIPH_SRC}/AES/aes_revb.c + ${PERIPH_SRC}/FLC/flc_common.c + ${PERIPH_SRC}/FLC/flc_ai87.c + ${PERIPH_SRC}/FLC/flc_reva.c + ${PERIPH_SRC}/GPIO/gpio_common.c + ${PERIPH_SRC}/GPIO/gpio_ai87.c + ${PERIPH_SRC}/GPIO/gpio_reva.c + ${PERIPH_SRC}/ICC/icc_ai87.c + ${PERIPH_SRC}/ICC/icc_reva.c + ${PERIPH_SRC}/TRNG/trng_ai87.c + ${PERIPH_SRC}/TRNG/trng_revb.c + ${PERIPH_SRC}/UART/uart_common.c + ${PERIPH_SRC}/UART/uart_ai87.c + ${PERIPH_SRC}/UART/uart_revb.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${MAX32_CMSIS}/Include + ${MAX32_CMSIS}/Device/Maxim/MAX78002/Include + ${MAX32_PERIPH}/Include/MAX78002 + ${PERIPH_SRC}/SYS + ${PERIPH_SRC}/GPIO + ${PERIPH_SRC}/AES + ${PERIPH_SRC}/TRNG + ${PERIPH_SRC}/ICC + ${PERIPH_SRC}/FLC + ${PERIPH_SRC}/UART + ) + + target_compile_options(${TARGET} PRIVATE + -Wno-error=strict-prototypes + -Wno-error=redundant-decls + ) + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_MAX78002 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/analog/max32/dcd_max32.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + target_compile_options(${TARGET}-tinyusb PRIVATE + -Wno-error=strict-prototypes + -Wno-error=redundant-decls + ) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/max78002/family.mk b/hw/bsp/max78002/family.mk new file mode 100644 index 000000000..825920596 --- /dev/null +++ b/hw/bsp/max78002/family.mk @@ -0,0 +1,104 @@ +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/analog/max32 + +# Important locations in the hw support for MCU +MAX32_CMSIS = hw/mcu/analog/max32/Libraries/CMSIS +MAX32_PERIPH = hw/mcu/analog/max32/Libraries/PeriphDrivers + +# Add any board specific make rules +include $(TOP)/$(BOARD_PATH)/board.mk + +CPU_CORE ?= cortex-m4 +PORT ?= 0 + +# GCC +SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX78002/Source/GCC/startup_max78002.S +LD_FILE = $(FAMILY_PATH)/max78002.ld + +# IAR +#SRC_S_IAR += + +# -------------- +# Compiler Flags +# -------------- +# Flags for the MAX78002 SDK +CFLAGS += -DTARGET=MAX78002 \ + -DTARGET_REV=0x4131 \ + -DMXC_ASSERT_ENABLE \ + -DMAX78002 \ + -DIAR_PRAGMAS=0 + +# Flags for TUSB features +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_MAX78002 \ + -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + +# mcu driver cause following warnings +CFLAGS += -Wno-error=redundant-decls \ + -Wno-error=strict-prototypes \ + -Wno-error=unused-parameter \ + -Wno-error=enum-conversion \ + -Wno-error=sign-compare \ + -Wno-error=cast-qual + +LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs + +# For flash-jlink target +JLINK_DEVICE = max78000 + +# flash target using Jlik +flash: flash-jlink + +# Optional flash option when running within an installed MSDK to use OpenOCD +# Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated. +# If the MSDK is installed, flash-msdk can be run to utilize the the modified +# openocd with the algorithms +MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) +flash-msdk: + $(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \ + -f interface/cmsis-dap.cfg -f target/max78002.cfg \ + -c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit" + +# ----------------- +# Sources & Include +# ----------------- +PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source +SRC_C += \ + src/portable/analog/max32/dcd_max32.c \ + $(MAX32_CMSIS)/Device/Maxim/MAX78002/Source/heap.c \ + $(MAX32_CMSIS)/Device/Maxim/MAX78002/Source/system_max78002.c \ + $(PERIPH_SRC)/SYS/mxc_assert.c \ + $(PERIPH_SRC)/SYS/mxc_delay.c \ + $(PERIPH_SRC)/SYS/mxc_lock.c \ + $(PERIPH_SRC)/SYS/nvic_table.c \ + $(PERIPH_SRC)/SYS/pins_ai87.c \ + $(PERIPH_SRC)/SYS/sys_ai87.c \ + $(PERIPH_SRC)/AES/aes_ai87.c \ + $(PERIPH_SRC)/AES/aes_revb.c \ + $(PERIPH_SRC)/FLC/flc_common.c \ + $(PERIPH_SRC)/FLC/flc_ai87.c \ + $(PERIPH_SRC)/FLC/flc_reva.c \ + $(PERIPH_SRC)/GPIO/gpio_common.c \ + $(PERIPH_SRC)/GPIO/gpio_ai87.c \ + $(PERIPH_SRC)/GPIO/gpio_reva.c \ + $(PERIPH_SRC)/ICC/icc_ai87.c \ + $(PERIPH_SRC)/ICC/icc_reva.c \ + $(PERIPH_SRC)/TRNG/trng_ai87.c \ + $(PERIPH_SRC)/TRNG/trng_revb.c \ + $(PERIPH_SRC)/UART/uart_common.c \ + $(PERIPH_SRC)/UART/uart_ai87.c \ + $(PERIPH_SRC)/UART/uart_revb.c \ + + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(MAX32_CMSIS)/Include \ + $(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX78002/Include \ + $(TOP)/$(MAX32_PERIPH)/Include/MAX78002 \ + $(PERIPH_SRC)/SYS \ + $(PERIPH_SRC)/GPIO \ + $(PERIPH_SRC)/AES \ + $(PERIPH_SRC)/ICC \ + $(PERIPH_SRC)/FLC \ + $(PERIPH_SRC)/TRNG \ + $(PERIPH_SRC)/UART diff --git a/hw/bsp/max78002/max78002.ld b/hw/bsp/max78002/max78002.ld new file mode 100644 index 000000000..5f9ed9356 --- /dev/null +++ b/hw/bsp/max78002/max78002.ld @@ -0,0 +1,180 @@ +MEMORY { + ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00010000 /* 64 kB ROM */ + FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x00280000 /* 2.5 MB Flash */ + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00060000 /* 384 kB SRAM */ + /*CSI2 (rwx) : ORIGIN = 0x2001F000, LENGTH = 0x00001000 4096 B CSI2 Buffer */ +} + +SECTIONS { + .rom : + { + KEEP(*(.rom_vector)) + *(.rom_handlers*) + } > ROM + + .text : + { + _text = .; + KEEP(*(.isr_vector)) + EXCLUDE_FILE (*riscv.o) *(.text*) /* Program code (exclude RISCV code) */ + *(.rodata*) /* read-only data: "const" */ + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + /* C++ Exception handling */ + KEEP(*(.eh_frame*)) + _etext = .; + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + /* Binary import */ + .bin_storage : + { + FILL(0xFF) + _bin_start_ = .; + KEEP(*(.bin_storage_img)) + _bin_end_ = .; + . = ALIGN(4); + } > FLASH + + .rom_code : + { + . = ALIGN(16); + _sran_code = .; + *(.rom_code_section) + _esran_code = .; + } > ROM + + .flash_code : + { + . = ALIGN(16); + _sran_code = .; + *(.flash_code_section) + _esran_code = .; + } > FLASH + + .sram_code : + { + . = ALIGN(16); + _sran_code = .; + *(.sram_code_section) + _esran_code = .; + } > SRAM + + /* it's used for C++ exception handling */ + /* we need to keep this to avoid overlapping */ + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + .data : + { + _data = ALIGN(., 4); + _csi = . + 0x20000; + *(vtable) + *(.data*) /*read-write initialized data: initialized global variable*/ + + + /* These array sections are used by __libc_init_array to call static C++ constructors */ + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + _edata = ALIGN(., 4); + + } > SRAM AT>FLASH + __load_data = LOADADDR(.data); + + .bss : + { + . = ALIGN(4); + _bss = .; + *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(COMMON) + _ebss = ALIGN(., 4); + } > SRAM + + .shared : + { + . = ALIGN(4); + _shared = .; + *(.mailbox*) + . = ALIGN(4); + *(.shared*) /*read-write zero initialized data: uninitialzed global variable*/ + _eshared = ALIGN(., 4); + } > SRAM + __shared_data = LOADADDR(.shared); + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(SRAM) + LENGTH(SRAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > SRAM + + .heap (COPY): + { + . = ALIGN(4); + *(.heap*) + __HeapLimit = ABSOLUTE(__StackLimit); + } > SRAM + + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack") + + /* Section used by RISCV loader projects. See RISCV_LOAD documentation in the build system. */ + .riscv_flash : + { + /* Align address to mod 256 with a small offset. This is required to match the flash page size.*/ + . = ALIGN(256); /* ALIGN operatator is used here. Note that (. & 0x1FFFFF00) was used in the past, but a strange bug was seen on Windows where the & did not behave as expected.*/ + . += 0x100; + _riscv_boot = .; + KEEP(*riscv.o (.text*)) + } > FLASH +} diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index a68e160bd..07cdf3ff0 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -455,7 +455,8 @@ //--------------------------------------------------------------------+ // Analog Devices //--------------------------------------------------------------------+ -#elif TU_CHECK_MCU(OPT_MCU_MAX32690) +#elif TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32666, \ + OPT_MCU_MAX32650, OPT_MCU_MAX78002) #define TUP_DCD_ENDPOINT_MAX 12 #define TUP_RHPORT_HIGHSPEED 1 diff --git a/src/portable/analog/max32/dcd_max32.c b/src/portable/analog/max32/dcd_max32.c index b3370ddd1..7226003de 100644 --- a/src/portable/analog/max32/dcd_max32.c +++ b/src/portable/analog/max32/dcd_max32.c @@ -27,7 +27,8 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && TU_CHECK_MCU(OPT_MCU_MAX32690) +#if CFG_TUD_ENABLED && \ + TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002) #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) /* GCC warns that an address may be unaligned, even though diff --git a/src/tusb_option.h b/src/tusb_option.h index 18f78b49c..1290d605c 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -190,6 +190,9 @@ // Analog Devices #define OPT_MCU_MAX32690 2400 ///< ADI MAX32690 +#define OPT_MCU_MAX32666 2401 ///< ADI MAX32666/5 +#define OPT_MCU_MAX32650 2402 ///< ADI MAX32650/1/2 +#define OPT_MCU_MAX78002 2403 ///< ADI MAX78002 // Check if configured MCU is one of listed // Apply _TU_CHECK_MCU with || as separator to list of input diff --git a/tools/get_deps.py b/tools/get_deps.py index e05cc4d76..fe548f4ab 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -26,7 +26,7 @@ deps_optional = { 'fc100s'], 'hw/mcu/analog/max32' : ['https://github.com/analogdevicesinc/msdk.git', 'b20b398d3e5e2007594e54a74ba3d2a2e50ddd75', - 'max32690'], + 'max32690 max32650 max32666 max78002'], 'hw/mcu/bridgetek/ft9xx/ft90x-sdk': ['https://github.com/BRTSG-FOSS/ft90x-sdk.git', '91060164afe239fcb394122e8bf9eb24d3194eb1', 'brtmm90x'], -- cgit v1.3.1 From 835a6ed62299ea29c04215d3a4547b74803661c6 Mon Sep 17 00:00:00 2001 From: Brent Kowal Date: Tue, 2 Jul 2024 11:54:23 -0400 Subject: Build System Updates Updated MAX32690 and MAX78002 linker and cmake scripts to work with CMake + Ninja build system. Verified all example projects build with the tools/build.py script for both board, and both make and cmake build systems. --- hw/bsp/max32690/family.cmake | 12 ++++++++---- hw/bsp/max32690/max32690.ld | 2 ++ hw/bsp/max78002/family.cmake | 8 +++++++- hw/bsp/max78002/max78002.ld | 2 ++ 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/hw/bsp/max32690/family.cmake b/hw/bsp/max32690/family.cmake index e1d797f58..8b117bae5 100644 --- a/hw/bsp/max32690/family.cmake +++ b/hw/bsp/max32690/family.cmake @@ -88,7 +88,7 @@ function(add_board_target BOARD_TARGET) ${PERIPH_SRC}/UART ) - target_compile_options(${TARGET} PRIVATE + target_compile_options(${BOARD_TARGET} PRIVATE -Wno-error=strict-prototypes ) update_board(${BOARD_TARGET}) @@ -139,10 +139,14 @@ function(family_configure_example TARGET RTOS) target_sources(${TARGET}-tinyusb PUBLIC ${TOP}/src/portable/analog/max32/dcd_max32.c ) - target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + target_compile_options(${TARGET} PRIVATE + -Wno-error=strict-prototypes + ) + + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) target_compile_options(${TARGET}-tinyusb PRIVATE - -Wno-error=strict-prototypes - ) + -Wno-error=strict-prototypes + ) # Link dependencies target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) diff --git a/hw/bsp/max32690/max32690.ld b/hw/bsp/max32690/max32690.ld index 35886fe3a..3d857b4e8 100644 --- a/hw/bsp/max32690/max32690.ld +++ b/hw/bsp/max32690/max32690.ld @@ -151,6 +151,8 @@ SECTIONS { .heap (COPY): { . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); *(.heap*) __HeapLimit = ABSOLUTE(__StackLimit); } > SRAM diff --git a/hw/bsp/max78002/family.cmake b/hw/bsp/max78002/family.cmake index 43b172b9f..28eaaa7e9 100644 --- a/hw/bsp/max78002/family.cmake +++ b/hw/bsp/max78002/family.cmake @@ -86,7 +86,7 @@ function(add_board_target BOARD_TARGET) ${PERIPH_SRC}/UART ) - target_compile_options(${TARGET} PRIVATE + target_compile_options(${BOARD_TARGET} PRIVATE -Wno-error=strict-prototypes -Wno-error=redundant-decls ) @@ -133,6 +133,12 @@ function(family_configure_example TARGET RTOS) ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) + target_compile_options(${TARGET} PRIVATE + -Wno-error=strict-prototypes + -Wno-error=redundant-decls + ) + + # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_MAX78002 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC diff --git a/hw/bsp/max78002/max78002.ld b/hw/bsp/max78002/max78002.ld index 5f9ed9356..60f99e28f 100644 --- a/hw/bsp/max78002/max78002.ld +++ b/hw/bsp/max78002/max78002.ld @@ -159,6 +159,8 @@ SECTIONS { .heap (COPY): { . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); *(.heap*) __HeapLimit = ABSOLUTE(__StackLimit); } > SRAM -- cgit v1.3.1 From 61beb6316d5a69b13c70fabaf71231da92394cc0 Mon Sep 17 00:00:00 2001 From: Brent Kowal Date: Tue, 2 Jul 2024 14:31:38 -0400 Subject: MAX32666 Support Added support for the MAX32666, Boards MAX32666EvKit and MAX32666FTHR. --- hw/bsp/max32666/FreeRTOSConfig/FreeRTOSConfig.h | 149 +++++++++++++++++++++ hw/bsp/max32666/boards/max32666evkit/board.cmake | 1 + hw/bsp/max32666/boards/max32666evkit/board.h | 57 ++++++++ hw/bsp/max32666/boards/max32666evkit/board.mk | 1 + hw/bsp/max32666/boards/max32666fthr/board.cmake | 1 + hw/bsp/max32666/boards/max32666fthr/board.h | 57 ++++++++ hw/bsp/max32666/boards/max32666fthr/board.mk | 1 + hw/bsp/max32666/family.c | 161 +++++++++++++++++++++++ hw/bsp/max32666/family.cmake | 151 +++++++++++++++++++++ hw/bsp/max32666/family.mk | 104 +++++++++++++++ hw/bsp/max32666/max32666.ld | 135 +++++++++++++++++++ 11 files changed, 818 insertions(+) create mode 100644 hw/bsp/max32666/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/max32666/boards/max32666evkit/board.cmake create mode 100644 hw/bsp/max32666/boards/max32666evkit/board.h create mode 100644 hw/bsp/max32666/boards/max32666evkit/board.mk create mode 100644 hw/bsp/max32666/boards/max32666fthr/board.cmake create mode 100644 hw/bsp/max32666/boards/max32666fthr/board.h create mode 100644 hw/bsp/max32666/boards/max32666fthr/board.mk create mode 100644 hw/bsp/max32666/family.c create mode 100644 hw/bsp/max32666/family.cmake create mode 100644 hw/bsp/max32666/family.mk create mode 100644 hw/bsp/max32666/max32666.ld diff --git a/hw/bsp/max32666/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/max32666/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..e5a76af85 --- /dev/null +++ b/hw/bsp/max32666/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "mxc_device.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS __NVIC_PRIO_BITS + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<clkcn & MXC_F_GCR_CLKCN_HIRC96M_EN)) { + MXC_GCR->clkcn |= MXC_F_GCR_CLKCN_HIRC96M_EN; + } + + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { +#if LED_STATE_ON + state = !state; +#endif + if (state) { + MXC_GPIO_OutClr(LED_PORT, LED_PIN); + } else { + MXC_GPIO_OutSet(LED_PORT, LED_PIN); + } +} + +uint32_t board_button_read(void) { + uint32_t state = MXC_GPIO_InGet(BUTTON_PORT, BUTTON_PIN) ? 1 : 0; + return BUTTON_STATE_ACTIVE == state; +} + +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN];//USN Buffer + /* All other 2nd parameter is optional checkum buffer */ + MXC_SYS_GetUSN(hw_id, NULL); + + size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN); + memcpy(id, hw_id, act_len); + return act_len; +} + +int board_uart_read(uint8_t *buf, int len) { + int uart_val; + int act_len = 0; + + while (act_len < len) { + if ((uart_val = MXC_UART_ReadCharacterRaw(ConsoleUart)) == E_UNDERFLOW) { + break; + } else { + *buf++ = (uint8_t) uart_val; + act_len++; + } + } + return act_len; +} + +int board_uart_write(void const *buf, int len) { + int act_len = 0; + const uint8_t *ch_ptr = (const uint8_t *) buf; + while (act_len < len) { + MXC_UART_WriteCharacter(ConsoleUart, *ch_ptr++); + act_len++; + } + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; +} + +uint32_t board_millis(void) { + return system_ticks; +} +#endif + +void HardFault_Handler(void) { + __asm("BKPT #0\n"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) { +} diff --git a/hw/bsp/max32666/family.cmake b/hw/bsp/max32666/family.cmake new file mode 100644 index 000000000..c9fa2510a --- /dev/null +++ b/hw/bsp/max32666/family.cmake @@ -0,0 +1,151 @@ +include_guard() + +set(MAX32_PERIPH ${TOP}/hw/mcu/analog/max32/Libraries/PeriphDrivers) +set(MAX32_CMSIS ${TOP}/hw/mcu/analog/max32/Libraries/CMSIS) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# Get the linker file from current location (family) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max32666.ld) +set(LD_FILE_Clang ${LD_FILE_GNU}) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(JLINK_DEVICE max32666) + +set(FAMILY_MCUS MAX32666 CACHE INTERNAL "") + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + TARGET=MAX32665 + TARGET_REV=0x4131 + MXC_ASSERT_ENABLE + MAX32665 + IAR_PRAGMAS=0 + CFG_TUSB_MCU=OPT_MCU_MAX32666 + BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + ) +endfunction() + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + # Startup & Linker script + set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX32665/Source/GCC/startup_max32665.S) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${MAX32_CMSIS}/Device/Maxim/MAX32665/Source/IAR/startup_max32665.S) + + set(PERIPH_SRC ${MAX32_PERIPH}/Source) + add_library(${BOARD_TARGET} STATIC + ${MAX32_CMSIS}/Device/Maxim/MAX32665/Source/heap.c + ${MAX32_CMSIS}/Device/Maxim/MAX32665/Source/system_max32665.c + ${PERIPH_SRC}/SYS/mxc_assert.c + ${PERIPH_SRC}/SYS/mxc_delay.c + ${PERIPH_SRC}/SYS/mxc_lock.c + ${PERIPH_SRC}/SYS/nvic_table.c + ${PERIPH_SRC}/SYS/pins_me14.c + ${PERIPH_SRC}/SYS/sys_me14.c + ${PERIPH_SRC}/TPU/tpu_me14.c + ${PERIPH_SRC}/TPU/tpu_reva.c + ${PERIPH_SRC}/FLC/flc_common.c + ${PERIPH_SRC}/FLC/flc_me14.c + ${PERIPH_SRC}/FLC/flc_reva.c + ${PERIPH_SRC}/GPIO/gpio_common.c + ${PERIPH_SRC}/GPIO/gpio_me14.c + ${PERIPH_SRC}/GPIO/gpio_reva.c + ${PERIPH_SRC}/ICC/icc_me14.c + ${PERIPH_SRC}/ICC/icc_reva.c + ${PERIPH_SRC}/UART/uart_common.c + ${PERIPH_SRC}/UART/uart_me14.c + ${PERIPH_SRC}/UART/uart_reva.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${MAX32_CMSIS}/Include + ${MAX32_CMSIS}/Device/Maxim/MAX32665/Include + ${MAX32_PERIPH}/Include/MAX32665 + ${PERIPH_SRC}/SYS + ${PERIPH_SRC}/GPIO + ${PERIPH_SRC}/TPU + ${PERIPH_SRC}/ICC + ${PERIPH_SRC}/FLC + ${PERIPH_SRC}/UART + ) + + target_compile_options(${BOARD_TARGET} PRIVATE + -Wno-error=strict-prototypes + ) + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_MAX32666 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/analog/max32/dcd_max32.c + ) + target_compile_options(${TARGET} PRIVATE + -Wno-error=strict-prototypes + ) + + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + target_compile_options(${TARGET}-tinyusb PRIVATE + -Wno-error=strict-prototypes + ) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/max32666/family.mk b/hw/bsp/max32666/family.mk new file mode 100644 index 000000000..d35b6d508 --- /dev/null +++ b/hw/bsp/max32666/family.mk @@ -0,0 +1,104 @@ +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/analog/max32 + +# Important locations in the hw support for MCU +MAX32_CMSIS = hw/mcu/analog/max32/Libraries/CMSIS +MAX32_PERIPH = hw/mcu/analog/max32/Libraries/PeriphDrivers + +# Add any board specific make rules +include $(TOP)/$(BOARD_PATH)/board.mk + +CPU_CORE ?= cortex-m4 +PORT ?= 0 + +# GCC +SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX32665/Source/GCC/startup_max32665.S +LD_FILE = $(FAMILY_PATH)/max32666.ld + +# IAR +#SRC_S_IAR += ? + +# -------------- +# Compiler Flags +# -------------- +# Flags for the MAX32665/6 SDK +CFLAGS += -DTARGET=MAX32665 \ + -DTARGET_REV=0x4131 \ + -DMXC_ASSERT_ENABLE \ + -DMAX32665 \ + -DIAR_PRAGMAS=0 + +# Flags for TUSB features +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_MAX32666 \ + -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + +# mcu driver cause following warnings +CFLAGS += -Wno-error=strict-prototypes \ + -Wno-error=unused-parameter \ + -Wno-error=cast-align \ + -Wno-error=cast-qual \ +# +# -Wno-error=old-style-declaration \ +# -Wno-error=sign-compare \ +# -Wno-error=cast-qual \ +# -Wno-lto-type-mismatch + +LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs + +# For flash-jlink target +JLINK_DEVICE = max32666 + +# flash target using Jlik +flash: flash-jlink + +# Optional flash option when running within an installed MSDK to use OpenOCD +# Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated. +# If the MSDK is installed, flash-msdk can be run to utilize the the modified +# openocd with the algorithms +MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) +flash-msdk: + $(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \ + -f interface/cmsis-dap.cfg -f target/max32665.cfg \ + -c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit" + +# ----------------- +# Sources & Include +# ----------------- +PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source +SRC_C += \ + src/portable/analog/max32/dcd_max32.c \ + $(MAX32_CMSIS)/Device/Maxim/MAX32665/Source/heap.c \ + $(MAX32_CMSIS)/Device/Maxim/MAX32665/Source/system_max32665.c \ + $(PERIPH_SRC)/SYS/mxc_assert.c \ + $(PERIPH_SRC)/SYS/mxc_delay.c \ + $(PERIPH_SRC)/SYS/mxc_lock.c \ + $(PERIPH_SRC)/SYS/nvic_table.c \ + $(PERIPH_SRC)/SYS/pins_me14.c \ + $(PERIPH_SRC)/SYS/sys_me14.c \ + $(PERIPH_SRC)/FLC/flc_common.c \ + $(PERIPH_SRC)/FLC/flc_me14.c \ + $(PERIPH_SRC)/FLC/flc_reva.c \ + $(PERIPH_SRC)/GPIO/gpio_common.c \ + $(PERIPH_SRC)/GPIO/gpio_me14.c \ + $(PERIPH_SRC)/GPIO/gpio_reva.c \ + $(PERIPH_SRC)/ICC/icc_me14.c \ + $(PERIPH_SRC)/ICC/icc_reva.c \ + $(PERIPH_SRC)/TPU/tpu_me14.c \ + $(PERIPH_SRC)/TPU/tpu_reva.c \ + $(PERIPH_SRC)/UART/uart_common.c \ + $(PERIPH_SRC)/UART/uart_me14.c \ + $(PERIPH_SRC)/UART/uart_reva.c \ + + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(MAX32_CMSIS)/Include \ + $(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX32665/Include \ + $(TOP)/$(MAX32_PERIPH)/Include/MAX32665 \ + $(PERIPH_SRC)/SYS \ + $(PERIPH_SRC)/GPIO \ + $(PERIPH_SRC)/ICC \ + $(PERIPH_SRC)/FLC \ + $(PERIPH_SRC)/TPU \ + $(PERIPH_SRC)/UART diff --git a/hw/bsp/max32666/max32666.ld b/hw/bsp/max32666/max32666.ld new file mode 100644 index 000000000..dcf61a3d0 --- /dev/null +++ b/hw/bsp/max32666/max32666.ld @@ -0,0 +1,135 @@ +/* SPID and SPIX Sections here are maximum possible sizes */ +/* If used, they should be adjusted for the external Flash/RAM size */ +MEMORY { + + SPIX (rx) : ORIGIN = 0x08000000, LENGTH = 0x08000000 + FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x00100000 + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0008C000 + SPID (rw) : ORIGIN = 0x80000000, LENGTH = 512M +} + +/* Sections Definitions */ +SECTIONS { + .text : + { + _text = .; + KEEP(*(.isr_vector)) + *(.text*) /* program code */ + *(.rodata*) /* read-only data: "const" */ + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + /* C++ Exception handling */ + KEEP(*(.eh_frame*)) + _etext = .; + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + /* This section will keep the SPIX data until loaded into the external device */ + /* Upon initialization of SPIX (user code needs to do this) */ + .xip_section : + { + KEEP(*(.xip_section*)) + } > SPIX AT>FLASH + + __load_start_xip = LOADADDR(.xip_section); + __load_length_xip = SIZEOF(.xip_section); + + /* it's used for C++ exception handling */ + /* we need to keep this to avoid overlapping */ + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + .data : + { + _data = ALIGN(., 4); + *(vtable) + *(.data*) /*read-write initialized data: initialized global variable*/ + *(.spix_config*) /* SPIX configuration functions need to be run from SRAM */ + *(.flashprog*) /* Flash program */ + + + /* These array sections are used by __libc_init_array to call static C++ constructors */ + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + _edata = ALIGN(., 4); + } > SRAM AT>FLASH + __load_data = LOADADDR(.data); + + .bss : + { + . = ALIGN(4); + _bss = .; + *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(COMMON) + _ebss = ALIGN(., 4); + } > SRAM + + /* Setup the stack for Core 1, it will only be used if the user code + * includes a definition of Stack_Size_Core1, which defines the space + * reserved above the main core's stack for core 1's stack */ + + __StackTop_Core1 = ORIGIN(SRAM) + LENGTH(SRAM); + __StackLimit_Core1 = DEFINED(Stack_Size_Core1) ? __StackTop_Core1 - Stack_Size_Core1 : __StackTop_Core1; + + /* Set stack top to end of RAM, and stack limit move down by Stack_Size. + * If core 1 is used, set the stack to the bottom of Core 1's stack region */ + + __StackTop = DEFINED(Stack_Size_Core1) ? __StackLimit_Core1 : ORIGIN(SRAM) + LENGTH(SRAM); + __StackLimit = __StackTop - Stack_Size; + + .heap (COPY): + { + . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + *(.heap*) + __HeapLimit = ABSOLUTE(__StackLimit); + } > SRAM + + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack(s) exceeds RAM limit */ + ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack") +} -- cgit v1.3.1 From 0c37f93bc850a881327714997ec1bfeaf69173ed Mon Sep 17 00:00:00 2001 From: Brent Kowal Date: Tue, 2 Jul 2024 18:02:11 -0400 Subject: MAX32650/1/2 Support Added support for the MAX32650/1/2 series parts - MAX32650FTHR, MAX32650EvKit, MAX32651EvKit - Added special flash rule for MAX32651 due to signing required - Added depencies to flash-msdk rules for executable --- hw/bsp/max32650/FreeRTOSConfig/FreeRTOSConfig.h | 149 +++++++++++++++++++++ hw/bsp/max32650/boards/max32650evkit/board.cmake | 1 + hw/bsp/max32650/boards/max32650evkit/board.h | 56 ++++++++ hw/bsp/max32650/boards/max32650evkit/board.mk | 17 +++ hw/bsp/max32650/boards/max32650evkit/max32650.ld | 119 +++++++++++++++++ hw/bsp/max32650/boards/max32650fthr/board.cmake | 1 + hw/bsp/max32650/boards/max32650fthr/board.h | 57 ++++++++ hw/bsp/max32650/boards/max32650fthr/board.mk | 17 +++ hw/bsp/max32650/boards/max32650fthr/max32650.ld | 119 +++++++++++++++++ hw/bsp/max32650/boards/max32651evkit/board.cmake | 1 + hw/bsp/max32650/boards/max32651evkit/board.h | 56 ++++++++ hw/bsp/max32650/boards/max32651evkit/board.mk | 42 ++++++ hw/bsp/max32650/boards/max32651evkit/max32651.ld | 132 +++++++++++++++++++ hw/bsp/max32650/family.c | 160 +++++++++++++++++++++++ hw/bsp/max32650/family.cmake | 152 +++++++++++++++++++++ hw/bsp/max32650/family.mk | 85 ++++++++++++ hw/bsp/max32666/boards/max32666fthr/board.h | 2 +- hw/bsp/max32666/family.mk | 10 +- hw/bsp/max32690/family.mk | 2 +- hw/bsp/max78002/family.mk | 2 +- 20 files changed, 1169 insertions(+), 11 deletions(-) create mode 100644 hw/bsp/max32650/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/max32650/boards/max32650evkit/board.cmake create mode 100644 hw/bsp/max32650/boards/max32650evkit/board.h create mode 100644 hw/bsp/max32650/boards/max32650evkit/board.mk create mode 100644 hw/bsp/max32650/boards/max32650evkit/max32650.ld create mode 100644 hw/bsp/max32650/boards/max32650fthr/board.cmake create mode 100644 hw/bsp/max32650/boards/max32650fthr/board.h create mode 100644 hw/bsp/max32650/boards/max32650fthr/board.mk create mode 100644 hw/bsp/max32650/boards/max32650fthr/max32650.ld create mode 100644 hw/bsp/max32650/boards/max32651evkit/board.cmake create mode 100644 hw/bsp/max32650/boards/max32651evkit/board.h create mode 100644 hw/bsp/max32650/boards/max32651evkit/board.mk create mode 100644 hw/bsp/max32650/boards/max32651evkit/max32651.ld create mode 100644 hw/bsp/max32650/family.c create mode 100644 hw/bsp/max32650/family.cmake create mode 100644 hw/bsp/max32650/family.mk diff --git a/hw/bsp/max32650/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/max32650/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..e5a76af85 --- /dev/null +++ b/hw/bsp/max32650/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "mxc_device.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS __NVIC_PRIO_BITS + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + /* it's used for C++ exception handling */ + /* we need to keep this to avoid overlapping */ + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + .data : + { + _data = ALIGN(., 4); + *(vtable) + *(.data*) /*read-write initialized data: initialized global variable*/ + *(.spix_config*) /* SPIX configuration functions need to be run from SRAM */ + *(.flashprog*) /* Flash program */ + + + /* These array sections are used by __libc_init_array to call static C++ constructors */ + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + _edata = ALIGN(., 4); + } > SRAM AT>FLASH + __load_data = LOADADDR(.data); + .bss : + { + . = ALIGN(4); + _bss = .; + *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(COMMON) + _ebss = ALIGN(., 4); + } > SRAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(SRAM) + LENGTH(SRAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > SRAM + + .heap (COPY): + { + . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + *(.heap*) + __HeapLimit = ABSOLUTE(__StackLimit); + } > SRAM + + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack") +} diff --git a/hw/bsp/max32650/boards/max32650fthr/board.cmake b/hw/bsp/max32650/boards/max32650fthr/board.cmake new file mode 100644 index 000000000..a9ce39b4d --- /dev/null +++ b/hw/bsp/max32650/boards/max32650fthr/board.cmake @@ -0,0 +1 @@ +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max32650.ld) diff --git a/hw/bsp/max32650/boards/max32650fthr/board.h b/hw/bsp/max32650/boards/max32650fthr/board.h new file mode 100644 index 000000000..d80a8fcae --- /dev/null +++ b/hw/bsp/max32650/boards/max32650fthr/board.h @@ -0,0 +1,57 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#include "gpio.h" +#include "mxc_sys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// LED +#define LED_PORT MXC_GPIO1 +#define LED_PIN MXC_GPIO_PIN_14 +#define LED_VDDIO MXC_GPIO_VSSEL_VDDIO +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PORT MXC_GPIO1 +#define BUTTON_PIN MXC_GPIO_PIN_19 +#define BUTTON_PULL MXC_GPIO_PAD_WEAK_PULL_UP +#define BUTTON_STATE_ACTIVE 0 + +// UART Enable for SWD UART Pins. Pin Mux handled by the HAL +#define UART_NUM 0 + + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/max32650/boards/max32650fthr/board.mk b/hw/bsp/max32650/boards/max32650fthr/board.mk new file mode 100644 index 000000000..c6f018810 --- /dev/null +++ b/hw/bsp/max32650/boards/max32650fthr/board.mk @@ -0,0 +1,17 @@ +LD_FILE = $(BOARD_PATH)/max32650.ld + +# For flash-jlink target +JLINK_DEVICE = max32650 + +# flash target using Jlik +flash: flash-jlink + +# Optional flash option when running within an installed MSDK to use OpenOCD +# Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated. +# If the MSDK is installed, flash-msdk can be run to utilize the the modified +# openocd with the algorithms +MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) +flash-msdk: $(BUILD)/$(PROJECT).elf + $(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \ + -f interface/cmsis-dap.cfg -f target/max32650.cfg \ + -c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit" diff --git a/hw/bsp/max32650/boards/max32650fthr/max32650.ld b/hw/bsp/max32650/boards/max32650fthr/max32650.ld new file mode 100644 index 000000000..3a1e5100d --- /dev/null +++ b/hw/bsp/max32650/boards/max32650fthr/max32650.ld @@ -0,0 +1,119 @@ +MEMORY { + ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00010000 /* 64kB ROM */ + FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x00300000 /* 3MB flash */ + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00100000 /* 1MB SRAM */ +} + +SECTIONS { + .text : + { + _text = .; + KEEP(*(.isr_vector)) + *(.text*) /* program code */ + *(.rodata*) /* read-only data: "const" */ + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + /* C++ Exception handling */ + KEEP(*(.eh_frame*)) + _etext = .; + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + /* it's used for C++ exception handling */ + /* we need to keep this to avoid overlapping */ + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + .data : + { + _data = ALIGN(., 4); + *(vtable) + *(.data*) /*read-write initialized data: initialized global variable*/ + *(.spix_config*) /* SPIX configuration functions need to be run from SRAM */ + *(.flashprog*) /* Flash program */ + + + /* These array sections are used by __libc_init_array to call static C++ constructors */ + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + _edata = ALIGN(., 4); + } > SRAM AT>FLASH + __load_data = LOADADDR(.data); + .bss : + { + . = ALIGN(4); + _bss = .; + *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(COMMON) + _ebss = ALIGN(., 4); + } > SRAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(SRAM) + LENGTH(SRAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > SRAM + + .heap (COPY): + { + . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + *(.heap*) + __HeapLimit = ABSOLUTE(__StackLimit); + } > SRAM + + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack") +} diff --git a/hw/bsp/max32650/boards/max32651evkit/board.cmake b/hw/bsp/max32650/boards/max32651evkit/board.cmake new file mode 100644 index 000000000..8bb3e6edd --- /dev/null +++ b/hw/bsp/max32650/boards/max32651evkit/board.cmake @@ -0,0 +1 @@ +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max32651.ld) \ No newline at end of file diff --git a/hw/bsp/max32650/boards/max32651evkit/board.h b/hw/bsp/max32650/boards/max32651evkit/board.h new file mode 100644 index 000000000..196abdaca --- /dev/null +++ b/hw/bsp/max32650/boards/max32651evkit/board.h @@ -0,0 +1,56 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#include "gpio.h" +#include "mxc_sys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// LED +#define LED_PORT MXC_GPIO2 +#define LED_PIN MXC_GPIO_PIN_25 +#define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PORT MXC_GPIO2 +#define BUTTON_PIN MXC_GPIO_PIN_28 +#define BUTTON_PULL MXC_GPIO_PAD_WEAK_PULL_UP +#define BUTTON_STATE_ACTIVE 0 + +// UART Enable for EvKit's Integrated FTDI Adapter. Pin Mux handled by the HAL +#define UART_NUM 0 + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/max32650/boards/max32651evkit/board.mk b/hw/bsp/max32650/boards/max32651evkit/board.mk new file mode 100644 index 000000000..8d13d8edf --- /dev/null +++ b/hw/bsp/max32650/boards/max32651evkit/board.mk @@ -0,0 +1,42 @@ +LD_FILE = $(BOARD_PATH)/max32651.ld +CFLAGS += -D__SLA_FWK__ + +# For flash-jlink target +JLINK_DEVICE = max32650 + +# flash target using MSDK signing the image +flash: flash-msdk-signed + + +MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) + +# The MAX32651EVKIT is pin for pin identical to the MAX32650EVKIT, however the +# MAX32651 has a secure bootloader which requires the image to be signed before +# loading into flash. All MAX32651EVKIT's have the same key for evaluation +# purposes, so create a special flash rule to sign the binary and flash using +# the MSDK. +# For the MAX32650, the regular flash, flash-jlink and flash-msdk are sufficient +MCU_PATH = $(TOP)/hw/mcu/analog/max32/ +# Assume no extension for sign utility +SIGN_EXE = sign_app +ifeq ($(OS), Windows_NT) +# Must use .exe extension on Windows, since the binaries +# for Linux may live in the same place. +SIGN_EXE := sign_app.exe +else +UNAME = $(shell uname -s) +ifneq ($(findstring MSYS_NT,$(UNAME)),) +# Must also use .exe extension for MSYS2 +SIGN_EXE := sign_app.exe +endif +endif + +flash-msdk-signed: $(BUILD)/$(PROJECT).elf + $(OBJCOPY) $(BUILD)/$(PROJECT).elf -R .sig -O binary $(BUILD)/$(PROJECT).bin + $(MCU_PATH)/Tools/SBT/bin/$(SIGN_EXE) -c MAX32651 key_file="$(MCU_PATH)/Tools/SBT/devices/MAX32651/keys/maximtestcrk.key" \ + ca=$(BUILD)/$(PROJECT).bin sca=$(BUILD)/$(PROJECT).sbin + $(OBJCOPY) $(BUILD)/$(PROJECT).elf --update-section .sig=$(BUILD)/$(PROJECT).sig + $(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \ + -f interface/cmsis-dap.cfg -f target/max32650.cfg \ + -c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit" + diff --git a/hw/bsp/max32650/boards/max32651evkit/max32651.ld b/hw/bsp/max32650/boards/max32651evkit/max32651.ld new file mode 100644 index 000000000..a873463d4 --- /dev/null +++ b/hw/bsp/max32650/boards/max32651evkit/max32651.ld @@ -0,0 +1,132 @@ +MEMORY { + HEADER (rx): ORIGIN = 0x10000000, LENGTH = 0x200 + FLASH (rx) : ORIGIN = 0x10000200, LENGTH = 0x002FFE00 /* 3MB flash */ + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00100000 /* 1MB SRAM */ +} + +/* Added Oct 9, 2018 to go to correct reset vector. */ +ENTRY(Reset_Handler) +PROVIDE( _start_SWAP = (((Reset_Handler) >> 24) | (((Reset_Handler) & 0x00FF0000) >> 8) | (((Reset_Handler) & 0x0000FF00) << 8) | ((Reset_Handler) << 24))); +PROVIDE_HIDDEN( _SLA_Size = _endimage - __end_header ); +PROVIDE( _SLA_Size_SWAP = (((_SLA_Size) >> 24) | (((_SLA_Size) & 0x00FF0000) >> 8) | (((_SLA_Size) & 0x0000FF00) << 8) | ((_SLA_Size) << 24))); + +/* Sections Definitions */ +SECTIONS { + .sb_sla_header : ALIGN(4) + { + FILL(0xFF) + KEEP(*(.sb_sla_header)) /* Header for ROM code */ + __end_header = . ; + . = ALIGN(512); + } > HEADER + + .text : + { + _text = .; + KEEP(*(.isr_vector)) + *(.text*) /* program code */ + *(.rodata*) /* read-only data: "const" */ + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* C++ Exception handling */ + KEEP(*(.eh_frame*)) + _etext = .; + } > FLASH + + /* it's used for C++ exception handling */ + /* we need to keep this to avoid overlapping */ + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } > FLASH + + .data : + { + _data = ALIGN(., 4); + *(.data*) /*read-write initialized data: initialized global variable*/ + *(.spix_config*) /* SPIX configuration functions need to be run from SRAM */ + *(.flashprog*) /* Flash program */ + + + /* These array sections are used by __libc_init_array to call static C++ constructors */ + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + _edata = ALIGN(., 4); + } > SRAM AT>FLASH + __load_data = LOADADDR(.data); + _enddata = LOADADDR(.data)+SIZEOF(.data); + + .sb_sla_trailer : AT(_enddata) + { + KEEP(*(.sb_sla_trailer)) + /* Align image with 16 byte boundary to conform to flash encryption block size. */ + FILL(0xDEADC0DE); + /* NOTE: The FILL and ALIGN will not work unless something is written to the section. So, we use LONG. */ + LONG(0xDEADC0DE); + . = ALIGN(16); + } > FLASH + _endimage = LOADADDR(.sb_sla_trailer)+SIZEOF(.sb_sla_trailer); + .sig : + { + KEEP(*(.sig)) + LONG(0xDEADBEEF); + + } > FLASH + .bss : + { + . = ALIGN(4); + _bss = .; + *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(COMMON) + _ebss = ALIGN(., 4); + } > SRAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(SRAM) + LENGTH(SRAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > SRAM + + .heap (COPY): + { + . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + *(.heap*) + __HeapLimit = ABSOLUTE(__StackLimit); + } > SRAM + + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack") +} diff --git a/hw/bsp/max32650/family.c b/hw/bsp/max32650/family.c new file mode 100644 index 000000000..16b5233b9 --- /dev/null +++ b/hw/bsp/max32650/family.c @@ -0,0 +1,160 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 Brent Kowal (Analog Devices, Inc) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "board.h" +#include "bsp/board_api.h" +#include "gpio.h" +#include "mxc_device.h" +#include "uart.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_IRQHandler(void) { + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ +mxc_uart_regs_t *ConsoleUart = MXC_UART_GET_UART(UART_NUM); + +void board_init(void) { +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + mxc_gpio_cfg_t gpioConfig; + + // LED + gpioConfig.drvstr = MXC_GPIO_DRVSTR_0; + gpioConfig.func = MXC_GPIO_FUNC_OUT; + gpioConfig.mask = LED_PIN; + gpioConfig.pad = MXC_GPIO_PAD_NONE; + gpioConfig.port = LED_PORT; + gpioConfig.vssel = LED_VDDIO; + MXC_GPIO_Config(&gpioConfig); + board_led_write(false); + + // Button + gpioConfig.drvstr = MXC_GPIO_DRVSTR_0; + gpioConfig.func = MXC_GPIO_FUNC_IN; + gpioConfig.mask = BUTTON_PIN; + gpioConfig.pad = BUTTON_PULL; + gpioConfig.port = BUTTON_PORT; + gpioConfig.vssel = MXC_GPIO_VSSEL_VDDIO; + MXC_GPIO_Config(&gpioConfig); + + // UART + MXC_UART_Init(ConsoleUart, CFG_BOARD_UART_BAUDRATE); + + //USB + // Startup the HIRC96M clock if it's not on already + if (!(MXC_GCR->clk_ctrl & MXC_F_GCR_CLK_CTRL_HIRC96_EN)) { + MXC_GCR->clk_ctrl |= MXC_F_GCR_CLK_CTRL_HIRC96_EN; + MXC_SYS_Clock_Timeout(MXC_F_GCR_CLK_CTRL_HIRC96_RDY); + } + + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { +#if LED_STATE_ON + state = !state; +#endif + if (state) { + MXC_GPIO_OutClr(LED_PORT, LED_PIN); + } else { + MXC_GPIO_OutSet(LED_PORT, LED_PIN); + } +} + +uint32_t board_button_read(void) { + uint32_t state = MXC_GPIO_InGet(BUTTON_PORT, BUTTON_PIN) ? 1 : 0; + return BUTTON_STATE_ACTIVE == state; +} + +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + uint8_t hw_id[13];//USN Buffer + MXC_SYS_GetUSN(hw_id, 13); + + size_t act_len = TU_MIN(max_len, 13); + memcpy(id, hw_id, act_len); + return act_len; +} + +int board_uart_read(uint8_t *buf, int len) { + int uart_val; + int act_len = 0; + + while (act_len < len) { + if ((uart_val = MXC_UART_ReadCharacterRaw(ConsoleUart)) == E_UNDERFLOW) { + break; + } else { + *buf++ = (uint8_t) uart_val; + act_len++; + } + } + return act_len; +} + +int board_uart_write(void const *buf, int len) { + int act_len = 0; + const uint8_t *ch_ptr = (const uint8_t *) buf; + while (act_len < len) { + MXC_UART_WriteCharacter(ConsoleUart, *ch_ptr++); + act_len++; + } + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; +} + +uint32_t board_millis(void) { + return system_ticks; +} +#endif + +void HardFault_Handler(void) { + __asm("BKPT #0\n"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) { +} diff --git a/hw/bsp/max32650/family.cmake b/hw/bsp/max32650/family.cmake new file mode 100644 index 000000000..764356495 --- /dev/null +++ b/hw/bsp/max32650/family.cmake @@ -0,0 +1,152 @@ +include_guard() + +set(MAX32_PERIPH ${TOP}/hw/mcu/analog/max32/Libraries/PeriphDrivers) +set(MAX32_CMSIS ${TOP}/hw/mcu/analog/max32/Libraries/CMSIS) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# Get the linker file from current location (family) +set(LD_FILE_Clang ${LD_FILE_GNU}) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(JLINK_DEVICE max32650) + +set(FAMILY_MCUS MAX32650 CACHE INTERNAL "") + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + TARGET=MAX32650 + TARGET_REV=0x4131 + MXC_ASSERT_ENABLE + MAX32650 + IAR_PRAGMAS=0 + CFG_TUSB_MCU=OPT_MCU_MAX32650 + BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + ) +endfunction() + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + # Startup & Linker script + set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX32650/Source/GCC/startup_max32650.S) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + #set(STARTUP_FILE_IAR ?) + + set(PERIPH_SRC ${MAX32_PERIPH}/Source) + add_library(${BOARD_TARGET} STATIC + ${MAX32_CMSIS}/Device/Maxim/MAX32650/Source/heap.c + ${MAX32_CMSIS}/Device/Maxim/MAX32650/Source/system_max32650.c + ${PERIPH_SRC}/SYS/mxc_assert.c + ${PERIPH_SRC}/SYS/mxc_delay.c + ${PERIPH_SRC}/SYS/mxc_lock.c + ${PERIPH_SRC}/SYS/nvic_table.c + ${PERIPH_SRC}/SYS/pins_me10.c + ${PERIPH_SRC}/SYS/sys_me10.c + ${PERIPH_SRC}/TPU/tpu_me10.c + ${PERIPH_SRC}/TPU/tpu_reva.c + ${PERIPH_SRC}/FLC/flc_common.c + ${PERIPH_SRC}/FLC/flc_me10.c + ${PERIPH_SRC}/FLC/flc_reva.c + ${PERIPH_SRC}/GPIO/gpio_common.c + ${PERIPH_SRC}/GPIO/gpio_me10.c + ${PERIPH_SRC}/GPIO/gpio_reva.c + ${PERIPH_SRC}/ICC/icc_me10.c + ${PERIPH_SRC}/ICC/icc_reva.c + ${PERIPH_SRC}/ICC/icc_common.c + ${PERIPH_SRC}/UART/uart_common.c + ${PERIPH_SRC}/UART/uart_me10.c + ${PERIPH_SRC}/UART/uart_reva.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${MAX32_CMSIS}/Include + ${MAX32_CMSIS}/Device/Maxim/MAX32650/Include + ${MAX32_PERIPH}/Include/MAX32650 + ${PERIPH_SRC}/SYS + ${PERIPH_SRC}/GPIO + ${PERIPH_SRC}/TPU + ${PERIPH_SRC}/ICC + ${PERIPH_SRC}/FLC + ${PERIPH_SRC}/UART + ) + + target_compile_options(${BOARD_TARGET} PRIVATE + -Wno-error=strict-prototypes + ) + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_MAX32650 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/analog/max32/dcd_max32.c + ) + target_compile_options(${TARGET} PRIVATE + -Wno-error=strict-prototypes + ) + + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + target_compile_options(${TARGET}-tinyusb PRIVATE + -Wno-error=strict-prototypes + ) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) +endfunction() + diff --git a/hw/bsp/max32650/family.mk b/hw/bsp/max32650/family.mk new file mode 100644 index 000000000..6e9b7b835 --- /dev/null +++ b/hw/bsp/max32650/family.mk @@ -0,0 +1,85 @@ +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/analog/max32 + +# Important locations in the hw support for MCU +MAX32_CMSIS = hw/mcu/analog/max32/Libraries/CMSIS +MAX32_PERIPH = hw/mcu/analog/max32/Libraries/PeriphDrivers + +# Add any board specific make rules +include $(TOP)/$(BOARD_PATH)/board.mk + +CPU_CORE ?= cortex-m4 +PORT ?= 0 + +# GCC +SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX32650/Source/GCC/startup_max32650.S + +# IAR +#SRC_S_IAR += ? + +# -------------- +# Compiler Flags +# -------------- +# Flags for the MAX32650/1/2 SDK +CFLAGS += -DTARGET=MAX32650 \ + -DTARGET_REV=0x4131 \ + -DMXC_ASSERT_ENABLE \ + -DMAX32650 \ + -DIAR_PRAGMAS=0 + +# Flags for TUSB features +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_MAX32650 \ + -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + +# mcu driver cause following warnings +CFLAGS += -Wno-error=strict-prototypes \ + -Wno-error=unused-parameter \ + -Wno-error=cast-align \ + -Wno-error=cast-qual \ + -Wno-error=sign-compare + +LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs + +# ----------------- +# Sources & Include +# ----------------- +PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source +SRC_C += \ + src/portable/analog/max32/dcd_max32.c \ + $(MAX32_CMSIS)/Device/Maxim/MAX32650/Source/heap.c \ + $(MAX32_CMSIS)/Device/Maxim/MAX32650/Source/system_max32650.c \ + $(MAX32_CMSIS)/Device/Maxim/MAX32650/Source/header_MAX32650.c \ + $(PERIPH_SRC)/SYS/mxc_assert.c \ + $(PERIPH_SRC)/SYS/mxc_delay.c \ + $(PERIPH_SRC)/SYS/mxc_lock.c \ + $(PERIPH_SRC)/SYS/nvic_table.c \ + $(PERIPH_SRC)/SYS/pins_me10.c \ + $(PERIPH_SRC)/SYS/sys_me10.c \ + $(PERIPH_SRC)/FLC/flc_common.c \ + $(PERIPH_SRC)/FLC/flc_me10.c \ + $(PERIPH_SRC)/FLC/flc_reva.c \ + $(PERIPH_SRC)/GPIO/gpio_common.c \ + $(PERIPH_SRC)/GPIO/gpio_me10.c \ + $(PERIPH_SRC)/GPIO/gpio_reva.c \ + $(PERIPH_SRC)/ICC/icc_me10.c \ + $(PERIPH_SRC)/ICC/icc_reva.c \ + $(PERIPH_SRC)/ICC/icc_common.c \ + $(PERIPH_SRC)/TPU/tpu_me10.c \ + $(PERIPH_SRC)/TPU/tpu_reva.c \ + $(PERIPH_SRC)/UART/uart_common.c \ + $(PERIPH_SRC)/UART/uart_me10.c \ + $(PERIPH_SRC)/UART/uart_reva.c \ + + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(MAX32_CMSIS)/Include \ + $(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX32650/Include \ + $(TOP)/$(MAX32_PERIPH)/Include/MAX32650 \ + $(PERIPH_SRC)/SYS \ + $(PERIPH_SRC)/GPIO \ + $(PERIPH_SRC)/ICC \ + $(PERIPH_SRC)/FLC \ + $(PERIPH_SRC)/TPU \ + $(PERIPH_SRC)/UART diff --git a/hw/bsp/max32666/boards/max32666fthr/board.h b/hw/bsp/max32666/boards/max32666fthr/board.h index 7e24266a1..c719b748a 100644 --- a/hw/bsp/max32666/boards/max32666fthr/board.h +++ b/hw/bsp/max32666/boards/max32666fthr/board.h @@ -46,7 +46,7 @@ extern "C" { #define BUTTON_PULL MXC_GPIO_PAD_PULL_UP #define BUTTON_STATE_ACTIVE 0 -// UART Enable for EvKit's Integrated FTDI Adapter. Pin Mux handled by the HAL +// UART Enable for UART on SWD. Pin Mux handled by the HAL #define UART_NUM 1 #define UART_MAP MAP_B diff --git a/hw/bsp/max32666/family.mk b/hw/bsp/max32666/family.mk index d35b6d508..31428cacd 100644 --- a/hw/bsp/max32666/family.mk +++ b/hw/bsp/max32666/family.mk @@ -36,13 +36,7 @@ CFLAGS += \ CFLAGS += -Wno-error=strict-prototypes \ -Wno-error=unused-parameter \ -Wno-error=cast-align \ - -Wno-error=cast-qual \ -# -# -Wno-error=old-style-declaration \ -# -Wno-error=sign-compare \ -# -Wno-error=cast-qual \ -# -Wno-lto-type-mismatch - + -Wno-error=cast-qual LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs # For flash-jlink target @@ -56,7 +50,7 @@ flash: flash-jlink # If the MSDK is installed, flash-msdk can be run to utilize the the modified # openocd with the algorithms MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) -flash-msdk: +flash-msdk: $(BUILD)/$(PROJECT).elf $(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \ -f interface/cmsis-dap.cfg -f target/max32665.cfg \ -c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit" diff --git a/hw/bsp/max32690/family.mk b/hw/bsp/max32690/family.mk index 08d5e8671..0405a2914 100644 --- a/hw/bsp/max32690/family.mk +++ b/hw/bsp/max32690/family.mk @@ -57,7 +57,7 @@ flash: flash-jlink # If the MSDK is installed, flash-msdk can be run to utilize the the modified # openocd with the algorithms MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) -flash-msdk: +flash-msdk: $(BUILD)/$(PROJECT).elf $(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \ -f interface/cmsis-dap.cfg -f target/max32690.cfg \ -c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit" diff --git a/hw/bsp/max78002/family.mk b/hw/bsp/max78002/family.mk index 825920596..04163417c 100644 --- a/hw/bsp/max78002/family.mk +++ b/hw/bsp/max78002/family.mk @@ -53,7 +53,7 @@ flash: flash-jlink # If the MSDK is installed, flash-msdk can be run to utilize the the modified # openocd with the algorithms MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) -flash-msdk: +flash-msdk: $(BUILD)/$(PROJECT).elf $(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \ -f interface/cmsis-dap.cfg -f target/max78002.cfg \ -c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit" -- cgit v1.3.1 From bd562e418080d4d9e4213d38a123b93f30250c48 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 5 Jul 2024 15:15:00 +0700 Subject: Revert "audio.h: fix error ISO C restricts enumerator values to range of 'int'" --- src/class/audio/audio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index 49ccbe863..d6f3e22e2 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -489,7 +489,7 @@ typedef enum AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2), AUDIO_DATA_FORMAT_TYPE_I_ALAW = (uint32_t) (1 << 3), AUDIO_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4), - AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = (int)(1U << 31U), + AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000, } audio_data_format_type_I_t; /// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification @@ -640,7 +640,7 @@ typedef enum AUDIO_CHANNEL_CONFIG_BOTTOM_CENTER = 0x01000000, AUDIO_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000, AUDIO_CHANNEL_CONFIG_BACK_RIGHT_OF_CENTER = 0x04000000, - AUDIO_CHANNEL_CONFIG_RAW_DATA = (int)(1U << 31U), + AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000, } audio_channel_config_t; /// AUDIO Channel Cluster Descriptor (4.1) -- cgit v1.3.1 From ca12a579020184c0e3f6d66d8081d5bb927cb4b2 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Jul 2024 15:19:16 +0700 Subject: add u for unsigned --- src/class/audio/audio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index d6f3e22e2..2f97c0f23 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -489,7 +489,7 @@ typedef enum AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2), AUDIO_DATA_FORMAT_TYPE_I_ALAW = (uint32_t) (1 << 3), AUDIO_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4), - AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000, + AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000u, } audio_data_format_type_I_t; /// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification @@ -640,7 +640,7 @@ typedef enum AUDIO_CHANNEL_CONFIG_BOTTOM_CENTER = 0x01000000, AUDIO_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000, AUDIO_CHANNEL_CONFIG_BACK_RIGHT_OF_CENTER = 0x04000000, - AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000, + AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000u, } audio_channel_config_t; /// AUDIO Channel Cluster Descriptor (4.1) -- cgit v1.3.1 From 8d5dbb957766921eba78b8762a458e6518521b66 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Jul 2024 15:40:02 +0700 Subject: add board_reset_to_bootloader(), try to implement that for ch32v203 but not working yet --- examples/device/cdc_dual_ports/src/main.c | 20 ++++++++++++++++ hw/bsp/board_api.h | 3 +++ hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.h | 2 +- hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.h | 2 +- hw/bsp/ch32v20x/family.c | 32 +++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/examples/device/cdc_dual_ports/src/main.c b/examples/device/cdc_dual_ports/src/main.c index 1167a5d50..ef12186f2 100644 --- a/examples/device/cdc_dual_ports/src/main.c +++ b/examples/device/cdc_dual_ports/src/main.c @@ -119,6 +119,26 @@ static void cdc_task(void) { } } +// Invoked when cdc when line state changed e.g connected/disconnected +// Use to reset to DFU when disconnect with 1200 bps +void tud_cdc_line_state_cb(uint8_t instance, bool dtr, bool rts) { + (void)rts; + + // DTR = false is counted as disconnected + if (!dtr) { + // touch1200 only with first CDC instance (Serial) + if (instance == 0) { + cdc_line_coding_t coding; + tud_cdc_get_line_coding(&coding); + if (coding.bit_rate == 1200) { + if (board_reset_to_bootloader) { + board_reset_to_bootloader(); + } + } + } + } +} + //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ diff --git a/hw/bsp/board_api.h b/hw/bsp/board_api.h index eee9ed9c5..774deca24 100644 --- a/hw/bsp/board_api.h +++ b/hw/bsp/board_api.h @@ -72,6 +72,9 @@ void board_init(void); // Init board after tinyusb is initialized void board_init_after_tusb(void) TU_ATTR_WEAK; +// Jump to bootloader +void board_reset_to_bootloader(void) TU_ATTR_WEAK; + // Turn LED on or off void board_led_write(bool state); diff --git a/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.h b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.h index 64eaf931e..692cf11bf 100644 --- a/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.h +++ b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.h @@ -6,7 +6,7 @@ extern "C" { #endif #define LED_PORT GPIOA -#define LED_PIN GPIO_Pin_15 +#define LED_PIN GPIO_Pin_0 #define LED_STATE_ON 0 #define UART_DEV USART1 diff --git a/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.h b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.h index d6c3a64c8..783831edd 100644 --- a/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.h +++ b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.h @@ -7,7 +7,7 @@ extern "C" { #define LED_PORT GPIOA #define LED_PIN GPIO_Pin_0 -#define LED_STATE_ON 1 +#define LED_STATE_ON 0 #define UART_DEV USART2 #define UART_CLOCK_EN() RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE) diff --git a/hw/bsp/ch32v20x/family.c b/hw/bsp/ch32v20x/family.c index ea98a5e19..e3075757e 100644 --- a/hw/bsp/ch32v20x/family.c +++ b/hw/bsp/ch32v20x/family.c @@ -139,6 +139,34 @@ void board_init(void) { __enable_irq(); } +void board_reset_to_bootloader(void) { + board_led_write(true); + + __disable_irq(); + +#if CFG_TUD_ENABLED + tud_deinit(0); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USB, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USB, DISABLE); +#endif + + SysTick->CTLR = 0; + for (int i = WWDG_IRQn; i< DMA1_Channel8_IRQn; i++) { + NVIC_DisableIRQ(i); + } + + __enable_irq(); + + // define function pointer to BOOT ROM address + void (*bootloader_entry)(void) = (void (*)(void))0x1FFF8000; + + bootloader_entry(); + + board_led_write(false); + + // while(1) { } +} + void board_led_write(bool state) { GPIO_WriteBit(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); } @@ -166,3 +194,7 @@ int board_uart_write(void const *buf, int len) { return len; } + +//-------------------------------------------------------------------- +// Neopixel +//-------------------------------------------------------------------- -- cgit v1.3.1 From c1175b70131fa5020713381a850f2ce1018f390f Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 10 Jul 2024 22:48:06 +0700 Subject: enable full 224KB flash for ch32v203 with flash enhanced read mode in SystemInit (better with startup). add flash with wlink-rs --- .gitignore | 60 +--------------------- examples/build_system/make/rules.mk | 6 +++ .../ch32v20x/boards/ch32v203c_r0_1v0/board.cmake | 5 +- hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.mk | 4 +- .../ch32v20x/boards/ch32v203g_r0_1v0/board.cmake | 5 +- hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.mk | 4 +- hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake | 5 +- hw/bsp/ch32v20x/boards/nanoch32v203/board.mk | 4 +- hw/bsp/ch32v20x/family.c | 48 +++++++++-------- hw/bsp/ch32v20x/family.cmake | 1 + hw/bsp/ch32v20x/family.mk | 3 +- hw/bsp/ch32v20x/system_ch32v20x.c | 11 +++- hw/bsp/family_support.cmake | 12 +++++ 13 files changed, 75 insertions(+), 93 deletions(-) diff --git a/.gitignore b/.gitignore index 7a37d65dc..f2150a26f 100644 --- a/.gitignore +++ b/.gitignore @@ -31,62 +31,4 @@ cov-int __pycache__ cmake-build-* sdkconfig - -# submodules -hw/mcu/allwinner -hw/mcu/bridgetek/ft9xx/ft90x-sdk -hw/mcu/broadcom -hw/mcu/gd/nuclei-sdk -hw/mcu/infineon/mtb-xmclib-cat3 -hw/mcu/microchip -hw/mcu/mindmotion/mm32sdk -hw/mcu/nordic/nrfx -hw/mcu/nuvoton -hw/mcu/nxp/lpcopen -hw/mcu/nxp/mcux-sdk -hw/mcu/nxp/nxp_sdk -hw/mcu/raspberry_pi/Pico-PIO-USB -hw/mcu/renesas/rx -hw/mcu/silabs/cmsis-dfp-efm32gg12b -hw/mcu/sony/cxd56/spresense-exported-sdk -hw/mcu/st/cmsis_device_f0 -hw/mcu/st/cmsis_device_f1 -hw/mcu/st/cmsis_device_f2 -hw/mcu/st/cmsis_device_f3 -hw/mcu/st/cmsis_device_f4 -hw/mcu/st/cmsis_device_f7 -hw/mcu/st/cmsis_device_g0 -hw/mcu/st/cmsis_device_g4 -hw/mcu/st/cmsis_device_h5 -hw/mcu/st/cmsis_device_h7 -hw/mcu/st/cmsis_device_l0 -hw/mcu/st/cmsis_device_l1 -hw/mcu/st/cmsis_device_l4 -hw/mcu/st/cmsis_device_l5 -hw/mcu/st/cmsis_device_u5 -hw/mcu/st/cmsis_device_wb -hw/mcu/st/stm32f0xx_hal_driver -hw/mcu/st/stm32f1xx_hal_driver -hw/mcu/st/stm32f2xx_hal_driver -hw/mcu/st/stm32f3xx_hal_driver -hw/mcu/st/stm32f4xx_hal_driver -hw/mcu/st/stm32f7xx_hal_driver -hw/mcu/st/stm32g0xx_hal_driver -hw/mcu/st/stm32g4xx_hal_driver -hw/mcu/st/stm32h5xx_hal_driver -hw/mcu/st/stm32h7xx_hal_driver -hw/mcu/st/stm32l0xx_hal_driver -hw/mcu/st/stm32l1xx_hal_driver -hw/mcu/st/stm32l4xx_hal_driver -hw/mcu/st/stm32l5xx_hal_driver -hw/mcu/st/stm32u5xx_hal_driver -hw/mcu/st/stm32wbxx_hal_driver -hw/mcu/ti -hw/mcu/wch/ch32v20x -hw/mcu/wch/ch32v307 -hw/mcu/wch/ch32f20x -lib/CMSIS_5 -lib/FreeRTOS-Kernel -lib/lwip -lib/sct_neopixel -tools/uf2 +.PVS-Studio diff --git a/examples/build_system/make/rules.mk b/examples/build_system/make/rules.mk index 102c6db0c..f322dbae6 100644 --- a/examples/build_system/make/rules.mk +++ b/examples/build_system/make/rules.mk @@ -145,6 +145,12 @@ OPENOCD_WCH_OPTION ?= flash-openocd-wch: $(BUILD)/$(PROJECT).elf $(OPENOCD_WCH) $(OPENOCD_WCH_OPTION) -c init -c halt -c "flash write_image $<" -c reset -c exit +# --------------- wlink-rs ----------------- +# flash with https://github.com/ch32-rs/wlink +WLINK_RS ?= wlink +flash-wlink-rs: $(BUILD)/$(PROJECT).elf + $(WLINK_RS) flash $< + # --------------- dfu-util ----------------- DFU_UTIL_OPTION ?= -a 0 flash-dfu-util: $(BUILD)/$(PROJECT).bin diff --git a/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake index 3dd87d3de..adb0ea741 100644 --- a/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake +++ b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake @@ -1,6 +1,8 @@ set(MCU_VARIANT D6) -set(LD_FLASH_SIZE 64K) +# 64KB zero-wait, 224KB total flash +#set(LD_FLASH_SIZE 64K) +set(LD_FLASH_SIZE 224K) set(LD_RAM_SIZE 20K) # set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${CH32_FAMILY}_tinyuf2.ld) @@ -8,6 +10,7 @@ set(LD_RAM_SIZE 20K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC SYSCLK_FREQ_144MHz_HSE=144000000 + CH32_FLASH_ENHANCE_READ_MODE=1 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() diff --git a/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.mk b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.mk index 7d5894629..bdd15f737 100644 --- a/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.mk +++ b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.mk @@ -2,8 +2,10 @@ MCU_VARIANT = D6 CFLAGS += \ -DSYSCLK_FREQ_144MHz_HSE=144000000 \ + -DCH32_FLASH_ENHANCE_READ_MODE=1 \ -DCFG_EXAMPLE_MSC_DUAL_READONLY \ +# 64KB zero-wait, 224KB total flash LDFLAGS += \ - -Wl,--defsym=__FLASH_SIZE=64K \ + -Wl,--defsym=__FLASH_SIZE=224K \ -Wl,--defsym=__RAM_SIZE=20K \ diff --git a/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake index 6e5305212..6fe3e05b2 100644 --- a/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake +++ b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake @@ -1,11 +1,14 @@ set(MCU_VARIANT D6) -set(LD_FLASH_SIZE 32K) +# 32KB zero-wait, 224KB total flash +#set(LD_FLASH_SIZE 32K) +set(LD_FLASH_SIZE 224K) set(LD_RAM_SIZE 10K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC SYSCLK_FREQ_144MHz_HSI=144000000 + CH32_FLASH_ENHANCE_READ_MODE=1 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() diff --git a/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.mk b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.mk index e5e4d63ba..f71f53478 100644 --- a/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.mk +++ b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.mk @@ -2,8 +2,10 @@ MCU_VARIANT = D6 CFLAGS += \ -DSYSCLK_FREQ_144MHz_HSI=144000000 \ + -DCH32_FLASH_ENHANCE_READ_MODE=1 \ -DCFG_EXAMPLE_MSC_DUAL_READONLY \ +# 32KB zero-wait, 224KB total flash LDFLAGS += \ - -Wl,--defsym=__FLASH_SIZE=32K \ + -Wl,--defsym=__FLASH_SIZE=224K \ -Wl,--defsym=__RAM_SIZE=10K \ diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake index f8dc862a7..ed7365797 100644 --- a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake @@ -1,11 +1,14 @@ set(MCU_VARIANT D6) -set(LD_FLASH_SIZE 64K) +# 64KB zero-wait, 224KB total flash +#set(LD_FLASH_SIZE 64K) +set(LD_FLASH_SIZE 224K) set(LD_RAM_SIZE 20K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC SYSCLK_FREQ_144MHz_HSE=144000000 + CH32_FLASH_ENHANCE_READ_MODE=1 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk b/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk index 7d5894629..362aace47 100644 --- a/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk @@ -2,8 +2,10 @@ MCU_VARIANT = D6 CFLAGS += \ -DSYSCLK_FREQ_144MHz_HSE=144000000 \ + -DCH32_FLASH_ENHANCE_READ_MODE=1 \ -DCFG_EXAMPLE_MSC_DUAL_READONLY \ +# 64KB zero-wait , 224KB total flash LDFLAGS += \ - -Wl,--defsym=__FLASH_SIZE=64K \ + -Wl,--defsym=__FLASH_SIZE=224K \ -Wl,--defsym=__RAM_SIZE=20K \ diff --git a/hw/bsp/ch32v20x/family.c b/hw/bsp/ch32v20x/family.c index e3075757e..542d4b5db 100644 --- a/hw/bsp/ch32v20x/family.c +++ b/hw/bsp/ch32v20x/family.c @@ -62,7 +62,6 @@ void USBWakeUp_IRQHandler(void) { #if CFG_TUSB_OS == OPT_OS_NONE - volatile uint32_t system_ticks = 0; __attribute__((interrupt)) @@ -84,7 +83,6 @@ uint32_t SysTick_Config(uint32_t ticks) { uint32_t board_millis(void) { return system_ticks; } - #endif void board_init(void) { @@ -140,29 +138,29 @@ void board_init(void) { } void board_reset_to_bootloader(void) { - board_led_write(true); - - __disable_irq(); - -#if CFG_TUD_ENABLED - tud_deinit(0); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_USB, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_USB, DISABLE); -#endif - - SysTick->CTLR = 0; - for (int i = WWDG_IRQn; i< DMA1_Channel8_IRQn; i++) { - NVIC_DisableIRQ(i); - } - - __enable_irq(); - - // define function pointer to BOOT ROM address - void (*bootloader_entry)(void) = (void (*)(void))0x1FFF8000; - - bootloader_entry(); - - board_led_write(false); +// board_led_write(true); +// +// __disable_irq(); +// +// #if CFG_TUD_ENABLED +// tud_deinit(0); +// RCC_APB1PeriphResetCmd(RCC_APB1Periph_USB, ENABLE); +// RCC_APB1PeriphResetCmd(RCC_APB1Periph_USB, DISABLE); +// #endif +// +// SysTick->CTLR = 0; +// for (int i = WWDG_IRQn; i< DMA1_Channel8_IRQn; i++) { +// NVIC_DisableIRQ(i); +// } +// +// __enable_irq(); +// +// // define function pointer to BOOT ROM address +// void (*bootloader_entry)(void) = (void (*)(void))0x1FFF8000; +// +// bootloader_entry(); +// +// board_led_write(false); // while(1) { } } diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake index faa79ed66..bf929b862 100644 --- a/hw/bsp/ch32v20x/family.cmake +++ b/hw/bsp/ch32v20x/family.cmake @@ -131,6 +131,7 @@ function(family_configure_example TARGET RTOS) # Flashing family_add_bin_hex(${TARGET}) family_flash_openocd_wch(${TARGET}) + family_flash_wlink_rs(${TARGET}) #family_add_uf2(${TARGET} ${UF2_FAMILY_ID}) #family_flash_uf2(${TARGET} ${UF2_FAMILY_ID}) diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index 4485091dc..08761dc0d 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -60,4 +60,5 @@ INC += \ FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -flash: flash-openocd-wch +flash: flash-wlink-rs +#flash: flash-openocd-wch diff --git a/hw/bsp/ch32v20x/system_ch32v20x.c b/hw/bsp/ch32v20x/system_ch32v20x.c index 435feae1b..882e7ed71 100644 --- a/hw/bsp/ch32v20x/system_ch32v20x.c +++ b/hw/bsp/ch32v20x/system_ch32v20x.c @@ -19,9 +19,9 @@ * If none of the define below is enabled, the HSI is used as System clock source. */ //#define SYSCLK_FREQ_HSE HSE_VALUE -//#define SYSCLK_FREQ_48MHz_HSE 48000000 +// #define SYSCLK_FREQ_48MHz_HSE 48000000 //#define SYSCLK_FREQ_56MHz_HSE 56000000 -//#define SYSCLK_FREQ_72MHz_HSE 72000000 +// #define SYSCLK_FREQ_72MHz_HSE 72000000 // #define SYSCLK_FREQ_96MHz_HSE 96000000 //#define SYSCLK_FREQ_120MHz_HSE 120000000 //#define SYSCLK_FREQ_144MHz_HSE 144000000 @@ -109,6 +109,13 @@ static void SetSysClockTo144_HSI( void ); */ void SystemInit (void) { + // Enable Flash enhance read mode for full 224KB +#if defined(CH32_FLASH_ENHANCE_READ_MODE) && CH32_FLASH_ENHANCE_READ_MODE == 1 + FLASH_Unlock_Fast(); + FLASH->CTLR |= (1 << 24); + FLASH_Lock_Fast(); +#endif + RCC->CTLR |= (uint32_t)0x00000001; RCC->CFGR0 &= (uint32_t)0xF8FF0000; RCC->CTLR &= (uint32_t)0xFEF6FFFF; diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 9f2e34691..bc2d481bb 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -455,6 +455,18 @@ function(family_flash_openocd_wch TARGET) family_flash_openocd(${TARGET}) endfunction() +# Add flash with https://github.com/ch32-rs/wlink +function(family_flash_wlink_rs TARGET) + if (NOT DEFINED WLINK_RS) + set(WLINK_RS wlink) + endif () + + add_custom_target(${TARGET}-wlink-rs + DEPENDS ${TARGET} + COMMAND ${WLINK_RS} flash $ + ) +endfunction() + # Add flash pycod target function(family_flash_pyocd TARGET) if (NOT DEFINED PYOC) -- cgit v1.3.1 From e251493a161b5a383fd7f8861e3bf7ea72bf872c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 10 Jul 2024 22:58:00 +0700 Subject: skip FLASH_ function to reduce dependency --- hw/bsp/ch32v20x/system_ch32v20x.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/hw/bsp/ch32v20x/system_ch32v20x.c b/hw/bsp/ch32v20x/system_ch32v20x.c index 882e7ed71..d32ee8d17 100644 --- a/hw/bsp/ch32v20x/system_ch32v20x.c +++ b/hw/bsp/ch32v20x/system_ch32v20x.c @@ -111,9 +111,12 @@ void SystemInit (void) { // Enable Flash enhance read mode for full 224KB #if defined(CH32_FLASH_ENHANCE_READ_MODE) && CH32_FLASH_ENHANCE_READ_MODE == 1 - FLASH_Unlock_Fast(); - FLASH->CTLR |= (1 << 24); - FLASH_Lock_Fast(); + FLASH->KEYR = 0x45670123; // FLASH_Unlock_Fast(); + FLASH->KEYR = 0xCDEF89AB; + + FLASH->CTLR |= (1 << 24); // Enhanced Read Mode + + FLASH->CTLR |= (1 << 15); // FLASH_Lock_Fast(); #endif RCC->CTLR |= (uint32_t)0x00000001; -- cgit v1.3.1 From f49725d2c958dd1368b5ca191a00be72543c0752 Mon Sep 17 00:00:00 2001 From: Brent Kowal Date: Wed, 10 Jul 2024 15:18:59 -0400 Subject: BSP Cleanup - Added MSDK flash rules for CMake - Removed partial IAR support. Uniform GCC support across MAX32 parts - Updated build scripts for correctly signing the MAX32651 - Added README files for the BSPs to describe flashing and limitiations --- hw/bsp/max32650/README.md | 46 +++++++++++++++++ hw/bsp/max32650/boards/max32650evkit/board.cmake | 11 +++- hw/bsp/max32650/boards/max32650evkit/board.mk | 17 +------ hw/bsp/max32650/boards/max32650fthr/board.cmake | 9 ++++ hw/bsp/max32650/boards/max32650fthr/board.mk | 17 +------ hw/bsp/max32650/boards/max32651evkit/board.cmake | 31 +++++++++++- hw/bsp/max32650/boards/max32651evkit/board.mk | 43 ++-------------- hw/bsp/max32650/family.cmake | 32 +++++++++--- hw/bsp/max32650/family.mk | 64 ++++++++++++++++++++++-- hw/bsp/max32666/README.md | 32 ++++++++++++ hw/bsp/max32666/family.cmake | 19 +++++-- hw/bsp/max32666/family.mk | 6 +-- hw/bsp/max32690/README.md | 31 ++++++++++++ hw/bsp/max32690/family.cmake | 21 +++++--- hw/bsp/max32690/family.mk | 6 +-- hw/bsp/max78002/README.md | 28 +++++++++++ hw/bsp/max78002/family.cmake | 27 ++++++---- hw/bsp/max78002/family.mk | 6 +-- 18 files changed, 325 insertions(+), 121 deletions(-) create mode 100644 hw/bsp/max32650/README.md create mode 100644 hw/bsp/max32666/README.md create mode 100644 hw/bsp/max32690/README.md create mode 100644 hw/bsp/max78002/README.md diff --git a/hw/bsp/max32650/README.md b/hw/bsp/max32650/README.md new file mode 100644 index 000000000..cb8069bba --- /dev/null +++ b/hw/bsp/max32650/README.md @@ -0,0 +1,46 @@ +# Analog Devices MAX32650/1/2 + +This BSP is for working with the Analog Devices +[MAX32650](https://www.analog.com/en/products/max32650.html), +[MAX32651](https://www.analog.com/en/products/max32651.html) and +[MAX32652](https://www.analog.com/en/products/max32652.html) +microcontrollers. The following boards are supported: + * [MAX32650EVKIT](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32650-evkit.html) + * [MAX32650FTHR](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32650fthr.html) + * [MAX32651EVKIT](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32651-evkit.html) (Secure Bootloader) + +This part family leverages the Maxim Microcontrollers SDK (MSDK) for the device +interfaces and hardware abstraction layers. This source code package is fetched +as part of the get-deps script. + +The microcontrollers utilize the standard GNU ARM toolchain. If this toolchain +is not already available on your build machine, it can be installed by using the +bundled MSDK installation. Details on downloading and installing can be found +in the [User's Guide](https://analogdevicesinc.github.io/msdk//USERGUIDE/). + +## Flashing + +### MAX32650 and MAX32652 + +The default flashing behavior in this BSP for the MAX32650 and MAX32652 is to +utilize JLink. This can be done by running the `flash` or `flash-jlink` rule +for Makefiles, or the `-jlink` target for CMake. + +Both the Evaluation Kit and Feather boards are shipped with a CMSIS-DAP +compatible debug probe. However, at the time of writing, the necessary flashing +algorithms for OpenOCD have not yet been incorporated into the OpenOCD master +branch. To utilize the provided debug probes, please install the bundled MSDK +package which includes the appropriate OpenOCD modifications. To leverage this +OpenOCD instance, run the `flash-msdk` Makefile rule, or `-msdk` CMake +target. + +### MAX32651 + +The MAX32651 features an integrated secure bootloader which requires the +application image be signed prior to flashing. Both the Makefile and CMake +scripts account for this signing automatically when building for the +MAX32651EVKIT. + +To flash the signed image, the MSDK's OpenOCD variant must be used. To flash +the MAX32651EVKIT please install the bundled MSDK, and utilize the `flash-msdk` +and `-msdk` rule and target. \ No newline at end of file diff --git a/hw/bsp/max32650/boards/max32650evkit/board.cmake b/hw/bsp/max32650/boards/max32650evkit/board.cmake index e094b89e1..fffdcc9fb 100644 --- a/hw/bsp/max32650/boards/max32650evkit/board.cmake +++ b/hw/bsp/max32650/boards/max32650evkit/board.cmake @@ -1 +1,10 @@ -set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max32650.ld) \ No newline at end of file +# Use the standard, non-secure linker file +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max32650.ld) + +function(update_board_extras TARGET) + #No extra arguments +endfunction() + +function(prepare_image TARGET_IN) + #No signing required +endfunction() diff --git a/hw/bsp/max32650/boards/max32650evkit/board.mk b/hw/bsp/max32650/boards/max32650evkit/board.mk index ad7125573..0bc210e11 100644 --- a/hw/bsp/max32650/boards/max32650evkit/board.mk +++ b/hw/bsp/max32650/boards/max32650evkit/board.mk @@ -1,17 +1,2 @@ +# Use the standard, non-secure linker file LD_FILE = $(BOARD_PATH)/max32650.ld - -# For flash-jlink target -JLINK_DEVICE = max32650 - -# flash target using Jlik -flash: flash-jlink - -# Optional flash option when running within an installed MSDK to use OpenOCD -# Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated. -# If the MSDK is installed, flash-msdk can be run to utilize the the modified -# openocd with the algorithms -MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) -flash-msdk: $(BUILD)/$(PROJECT).elf - $(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \ - -f interface/cmsis-dap.cfg -f target/max32650.cfg \ - -c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit" \ No newline at end of file diff --git a/hw/bsp/max32650/boards/max32650fthr/board.cmake b/hw/bsp/max32650/boards/max32650fthr/board.cmake index a9ce39b4d..fffdcc9fb 100644 --- a/hw/bsp/max32650/boards/max32650fthr/board.cmake +++ b/hw/bsp/max32650/boards/max32650fthr/board.cmake @@ -1 +1,10 @@ +# Use the standard, non-secure linker file set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max32650.ld) + +function(update_board_extras TARGET) + #No extra arguments +endfunction() + +function(prepare_image TARGET_IN) + #No signing required +endfunction() diff --git a/hw/bsp/max32650/boards/max32650fthr/board.mk b/hw/bsp/max32650/boards/max32650fthr/board.mk index c6f018810..0bc210e11 100644 --- a/hw/bsp/max32650/boards/max32650fthr/board.mk +++ b/hw/bsp/max32650/boards/max32650fthr/board.mk @@ -1,17 +1,2 @@ +# Use the standard, non-secure linker file LD_FILE = $(BOARD_PATH)/max32650.ld - -# For flash-jlink target -JLINK_DEVICE = max32650 - -# flash target using Jlik -flash: flash-jlink - -# Optional flash option when running within an installed MSDK to use OpenOCD -# Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated. -# If the MSDK is installed, flash-msdk can be run to utilize the the modified -# openocd with the algorithms -MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) -flash-msdk: $(BUILD)/$(PROJECT).elf - $(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \ - -f interface/cmsis-dap.cfg -f target/max32650.cfg \ - -c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit" diff --git a/hw/bsp/max32650/boards/max32651evkit/board.cmake b/hw/bsp/max32650/boards/max32651evkit/board.cmake index 8bb3e6edd..bd8077a42 100644 --- a/hw/bsp/max32650/boards/max32651evkit/board.cmake +++ b/hw/bsp/max32650/boards/max32651evkit/board.cmake @@ -1 +1,30 @@ -set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max32651.ld) \ No newline at end of file +# Use the secure linker file +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max32651.ld) + +function(update_board_extras TARGET) + # for the signed target, need to add the __SLA_FWK__ define + target_compile_definitions(${TARGET} PUBLIC + __SLA_FWK__ + ) +endfunction() + +function(prepare_image TARGET_IN) + #For the signed target, set up a POST_BUILD command to sign the elf file once + #created + if((WIN32) OR (MINGW) OR (MSYS)) + set(SIGN_EXE "sign_app.exe") + else() + set(SIGN_EXE "sign_app") + endif() + set(MCU_PATH "${TOP}/hw/mcu/analog/max32/") + + # Custom POST_BUILD command + add_custom_command( + TARGET ${TARGET_IN} POST_BUILD + COMMAND ${CMAKE_OBJCOPY} $ -R .sig -O binary $/${TARGET_IN}.bin + COMMAND ${MCU_PATH}/Tools/SBT/bin/${SIGN_EXE} -c MAX32651 key_file=${MCU_PATH}/Tools/SBT/devices/MAX32651/keys/maximtestcrk.key + ca=$/${TARGET_IN}.bin sca=$/${TARGET_IN}.sbin + COMMAND ${CMAKE_OBJCOPY} $ --update-section .sig=$/${TARGET_IN}.sig + VERBATIM + ) +endfunction() diff --git a/hw/bsp/max32650/boards/max32651evkit/board.mk b/hw/bsp/max32650/boards/max32651evkit/board.mk index 8d13d8edf..b609598c1 100644 --- a/hw/bsp/max32650/boards/max32651evkit/board.mk +++ b/hw/bsp/max32650/boards/max32651evkit/board.mk @@ -1,42 +1,5 @@ +# Use the secure linker file LD_FILE = $(BOARD_PATH)/max32651.ld -CFLAGS += -D__SLA_FWK__ - -# For flash-jlink target -JLINK_DEVICE = max32650 - -# flash target using MSDK signing the image -flash: flash-msdk-signed - - -MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) - -# The MAX32651EVKIT is pin for pin identical to the MAX32650EVKIT, however the -# MAX32651 has a secure bootloader which requires the image to be signed before -# loading into flash. All MAX32651EVKIT's have the same key for evaluation -# purposes, so create a special flash rule to sign the binary and flash using -# the MSDK. -# For the MAX32650, the regular flash, flash-jlink and flash-msdk are sufficient -MCU_PATH = $(TOP)/hw/mcu/analog/max32/ -# Assume no extension for sign utility -SIGN_EXE = sign_app -ifeq ($(OS), Windows_NT) -# Must use .exe extension on Windows, since the binaries -# for Linux may live in the same place. -SIGN_EXE := sign_app.exe -else -UNAME = $(shell uname -s) -ifneq ($(findstring MSYS_NT,$(UNAME)),) -# Must also use .exe extension for MSYS2 -SIGN_EXE := sign_app.exe -endif -endif - -flash-msdk-signed: $(BUILD)/$(PROJECT).elf - $(OBJCOPY) $(BUILD)/$(PROJECT).elf -R .sig -O binary $(BUILD)/$(PROJECT).bin - $(MCU_PATH)/Tools/SBT/bin/$(SIGN_EXE) -c MAX32651 key_file="$(MCU_PATH)/Tools/SBT/devices/MAX32651/keys/maximtestcrk.key" \ - ca=$(BUILD)/$(PROJECT).bin sca=$(BUILD)/$(PROJECT).sbin - $(OBJCOPY) $(BUILD)/$(PROJECT).elf --update-section .sig=$(BUILD)/$(PROJECT).sig - $(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \ - -f interface/cmsis-dap.cfg -f target/max32650.cfg \ - -c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit" +# Let the family script know the build needs to be signed +SIGNED_BUILD := 1 diff --git a/hw/bsp/max32650/family.cmake b/hw/bsp/max32650/family.cmake index 764356495..129d99af8 100644 --- a/hw/bsp/max32650/family.cmake +++ b/hw/bsp/max32650/family.cmake @@ -4,10 +4,10 @@ set(MAX32_PERIPH ${TOP}/hw/mcu/analog/max32/Libraries/PeriphDrivers) set(MAX32_CMSIS ${TOP}/hw/mcu/analog/max32/Libraries/CMSIS) set(CMSIS_5 ${TOP}/lib/CMSIS_5) -# include board specific +# include board specific information and functions include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) -# Get the linker file from current location (family) +# Get the linker file set(LD_FILE_Clang ${LD_FILE_GNU}) # toolchain set up @@ -27,6 +27,9 @@ function(update_board TARGET) CFG_TUSB_MCU=OPT_MCU_MAX32650 BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED ) + + # Run any board specific updates + update_board_extras(${TARGET}) endfunction() #------------------------------------ @@ -41,11 +44,11 @@ function(add_board_target BOARD_TARGET) # Startup & Linker script set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX32650/Source/GCC/startup_max32650.S) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - #set(STARTUP_FILE_IAR ?) set(PERIPH_SRC ${MAX32_PERIPH}/Source) add_library(${BOARD_TARGET} STATIC ${MAX32_CMSIS}/Device/Maxim/MAX32650/Source/heap.c + ${MAX32_CMSIS}/Device/Maxim/MAX32650/Source/header_MAX32650.c ${MAX32_CMSIS}/Device/Maxim/MAX32650/Source/system_max32650.c ${PERIPH_SRC}/SYS/mxc_assert.c ${PERIPH_SRC}/SYS/mxc_delay.c @@ -84,7 +87,7 @@ function(add_board_target BOARD_TARGET) ) target_compile_options(${BOARD_TARGET} PRIVATE - -Wno-error=strict-prototypes + -Wno-error=strict-prototypes ) update_board(${BOARD_TARGET}) @@ -93,15 +96,12 @@ function(add_board_target BOARD_TARGET) "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs + -u sb_header #Needed when linking libraries to not lose the Signing header ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) endif () endfunction() @@ -148,5 +148,21 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_jlink(${TARGET}) + + # Add the optional MSDK OpenOCD flashing + family_flash_msdk(${TARGET}) endfunction() +function(family_flash_msdk TARGET) + # Prepare the image (signed) if the board requires it + prepare_image(${TARGET}) + + set(MAXIM_PATH "$ENV{MAXIM_PATH}") + add_custom_target(${TARGET}-msdk + DEPENDS ${TARGET} + COMMAND ${MAXIM_PATH}/Tools/OpenOCD/openocd -s ${MAXIM_PATH}/Tools/OpenOCD/scripts + -f interface/cmsis-dap.cfg -f target/max32650.cfg + -c "program $ verify; init; reset; exit" + VERBATIM + ) +endfunction() diff --git a/hw/bsp/max32650/family.mk b/hw/bsp/max32650/family.mk index 6e9b7b835..577d96717 100644 --- a/hw/bsp/max32650/family.mk +++ b/hw/bsp/max32650/family.mk @@ -13,9 +13,6 @@ PORT ?= 0 # GCC SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX32650/Source/GCC/startup_max32650.S -# IAR -#SRC_S_IAR += ? - # -------------- # Compiler Flags # -------------- @@ -40,6 +37,26 @@ CFLAGS += -Wno-error=strict-prototypes \ LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs +# Configure the flash rule. By default, use JLink. +SIGNED_BUILD ?= 0 +DEFAULT_FLASH = flash-jlink + +# If the applications needs to be signed (for the MAX32651), sign it first and +# then need to use MSDK's OpenOCD to flash it +# Also need to include the __SLA_FWK__ define to enable the signed header into +# memory +ifeq ($(SIGNED_BUILD), 1) +# Extra definitions to build for the secure part +CFLAGS += -D__SLA_FWK__ +DEFAULT_FLASH := sign-build flash-msdk +endif + +# For flash-jlink target +JLINK_DEVICE = max32650 + +# Configure the flash rule +flash: $(DEFAULT_FLASH) + # ----------------- # Sources & Include # ----------------- @@ -70,7 +87,6 @@ SRC_C += \ $(PERIPH_SRC)/UART/uart_me10.c \ $(PERIPH_SRC)/UART/uart_reva.c \ - INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ @@ -83,3 +99,43 @@ INC += \ $(PERIPH_SRC)/FLC \ $(PERIPH_SRC)/TPU \ $(PERIPH_SRC)/UART + + +# The MAX32651EVKIT is pin for pin identical to the MAX32650EVKIT, however the +# MAX32651 has a secure bootloader which requires the image to be signed before +# loading into flash. All MAX32651EVKIT's have the same key for evaluation +# purposes, so create a special flash rule to sign the binary and flash using +# the MSDK. +MCU_PATH = $(TOP)/hw/mcu/analog/max32/ +# Assume no extension for sign utility +SIGN_EXE = sign_app +ifeq ($(OS), Windows_NT) +# Must use .exe extension on Windows, since the binaries +# for Linux may live in the same place. +SIGN_EXE := sign_app.exe +else +UNAME = $(shell uname -s) +ifneq ($(findstring MSYS_NT,$(UNAME)),) +# Must also use .exe extension for MSYS2 +SIGN_EXE := sign_app.exe +endif +endif + +# Rule to sign the build. This will in-place modifiy the existing .elf file +# an populate the .sig section with the signature value +sign-build: $(BUILD)/$(PROJECT).elf + $(OBJCOPY) $(BUILD)/$(PROJECT).elf -R .sig -O binary $(BUILD)/$(PROJECT).bin + $(MCU_PATH)/Tools/SBT/bin/$(SIGN_EXE) -c MAX32651 \ + key_file="$(MCU_PATH)/Tools/SBT/devices/MAX32651/keys/maximtestcrk.key" \ + ca=$(BUILD)/$(PROJECT).bin sca=$(BUILD)/$(PROJECT).sbin + $(OBJCOPY) $(BUILD)/$(PROJECT).elf --update-section .sig=$(BUILD)/$(PROJECT).sig + +# Optional flash option when running within an installed MSDK to use OpenOCD +# Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated. +# If the MSDK is installed, flash-msdk can be run to utilize the the modified +# openocd with the algorithms +MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) +flash-msdk: $(BUILD)/$(PROJECT).elf + $(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \ + -f interface/cmsis-dap.cfg -f target/max32650.cfg \ + -c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit" diff --git a/hw/bsp/max32666/README.md b/hw/bsp/max32666/README.md new file mode 100644 index 000000000..902d82e25 --- /dev/null +++ b/hw/bsp/max32666/README.md @@ -0,0 +1,32 @@ +# Analog Devices MAX32665/6 + +This BSP is for working with the Analog Devices +[MAX32665](https://www.analog.com/en/products/max32665.html) and +[MAX32666](https://www.analog.com/en/products/max32666.html) microcontrollers. +The following boards are supported: + * [MAX32666EVKIT](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32666evkit.html) + * [MAX32666FTHR](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32666fthr.html) + + +This part family leverages the Maxim Microcontrollers SDK (MSDK) for the device +interfaces and hardware abstraction layers. This source code package is fetched +as part of the get-deps script. + +The microcontrollers utilize the standard GNU ARM toolchain. If this toolchain +is not already available on your build machine, it can be installed by using the +bundled MSDK installation. Details on downloading and installing can be found +in the [User's Guide](https://analogdevicesinc.github.io/msdk//USERGUIDE/). + +## Flashing + +The default flashing behavior in this BSP is to utilize JLink. This can be done +by running the `flash` or `flash-jlink` rule for Makefiles, or the +`-jlink` target for CMake. + +Both the Evaluation Kit and Feather boards are shipped with a CMSIS-DAP +compatible debug probe. However, at the time of writing, the necessary flashing +algorithms for OpenOCD have not yet been incorporated into the OpenOCD master +branch. To utilize the provided debug probes, please install the bundled MSDK +package which includes the appropriate OpenOCD modifications. To leverage this +OpenOCD instance, run the `flash-msdk` Makefile rule, or `-msdk` CMake +target. diff --git a/hw/bsp/max32666/family.cmake b/hw/bsp/max32666/family.cmake index c9fa2510a..ef2a2bb63 100644 --- a/hw/bsp/max32666/family.cmake +++ b/hw/bsp/max32666/family.cmake @@ -42,7 +42,6 @@ function(add_board_target BOARD_TARGET) # Startup & Linker script set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX32665/Source/GCC/startup_max32665.S) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - set(STARTUP_FILE_IAR ${MAX32_CMSIS}/Device/Maxim/MAX32665/Source/IAR/startup_max32665.S) set(PERIPH_SRC ${MAX32_PERIPH}/Source) add_library(${BOARD_TARGET} STATIC @@ -98,10 +97,6 @@ function(add_board_target BOARD_TARGET) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) endif () endfunction() @@ -148,4 +143,18 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_jlink(${TARGET}) + family_flash_msdk(${TARGET}) +endfunction() + +# Add flash msdk target +function(family_flash_msdk TARGET) + set(MAXIM_PATH "$ENV{MAXIM_PATH}") + + add_custom_target(${TARGET}-msdk + DEPENDS ${TARGET} + COMMAND ${MAXIM_PATH}/Tools/OpenOCD/openocd -s ${MAXIM_PATH}/Tools/OpenOCD/scripts + -f interface/cmsis-dap.cfg -f target/max32665.cfg + -c "program $ verify; init; reset; exit" + VERBATIM + ) endfunction() diff --git a/hw/bsp/max32666/family.mk b/hw/bsp/max32666/family.mk index 31428cacd..31f81f014 100644 --- a/hw/bsp/max32666/family.mk +++ b/hw/bsp/max32666/family.mk @@ -14,9 +14,6 @@ PORT ?= 0 SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX32665/Source/GCC/startup_max32665.S LD_FILE = $(FAMILY_PATH)/max32666.ld -# IAR -#SRC_S_IAR += ? - # -------------- # Compiler Flags # -------------- @@ -42,7 +39,7 @@ LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs # For flash-jlink target JLINK_DEVICE = max32666 -# flash target using Jlik +# flash target using Jlink by default flash: flash-jlink # Optional flash option when running within an installed MSDK to use OpenOCD @@ -83,7 +80,6 @@ SRC_C += \ $(PERIPH_SRC)/UART/uart_me14.c \ $(PERIPH_SRC)/UART/uart_reva.c \ - INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ diff --git a/hw/bsp/max32690/README.md b/hw/bsp/max32690/README.md new file mode 100644 index 000000000..081ae0ad4 --- /dev/null +++ b/hw/bsp/max32690/README.md @@ -0,0 +1,31 @@ +# Analog Devices MAX32690 + +This BSP is for working with the Analog Devices +[MAX32690](https://www.analog.com/en/products/max32690.html) microcontroller. +The following boards are supported: + * [MAX32690EVKIT](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32690evkit.html) + * [AD-APARD32690-SL](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/ad-apard32690-sl.html) + + +This part family leverages the Maxim Microcontrollers SDK (MSDK) for the device +interfaces and hardware abstraction layers. This source code package is fetched +as part of the get-deps script. + +The microcontroller utilizes the standard GNU ARM toolchain. If this toolchain +is not already available on your build machine, it can be installed by using the +bundled MSDK installation. Details on downloading and installing can be found +in the [User's Guide](https://analogdevicesinc.github.io/msdk//USERGUIDE/). + +## Flashing + +The default flashing behavior in this BSP is to utilize JLink. This can be done +by running the `flash` or `flash-jlink` rule for Makefiles, or the +`-jlink` target for CMake. + +Both the Evaluation Kit and APARD boards are shipped with a CMSIS-DAP +compatible debug probe. However, at the time of writing, the necessary flashing +algorithms for OpenOCD have not yet been incorporated into the OpenOCD master +branch. To utilize the provided debug probes, please install the bundled MSDK +package which includes the appropriate OpenOCD modifications. To leverage this +OpenOCD instance, run the `flash-msdk` Makefile rule, or `-msdk` CMake +target. diff --git a/hw/bsp/max32690/family.cmake b/hw/bsp/max32690/family.cmake index 8b117bae5..5c470f86b 100644 --- a/hw/bsp/max32690/family.cmake +++ b/hw/bsp/max32690/family.cmake @@ -46,7 +46,6 @@ function(add_board_target BOARD_TARGET) # Startup & Linker script set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX32690/Source/GCC/startup_max32690.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - set(STARTUP_FILE_IAR ${MAX32_CMSIS}/Device/Maxim/MAX32690/Source/IAR/startup_max32690.s) set(PERIPH_SRC ${MAX32_PERIPH}/Source) add_library(${BOARD_TARGET} STATIC @@ -89,7 +88,7 @@ function(add_board_target BOARD_TARGET) ) target_compile_options(${BOARD_TARGET} PRIVATE - -Wno-error=strict-prototypes + -Wno-error=strict-prototypes ) update_board(${BOARD_TARGET}) @@ -103,10 +102,6 @@ function(add_board_target BOARD_TARGET) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) endif () endfunction() @@ -153,4 +148,18 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_jlink(${TARGET}) + family_flash_msdk(${TARGET}) +endfunction() + +# Add flash msdk target +function(family_flash_msdk TARGET) + set(MAXIM_PATH "$ENV{MAXIM_PATH}") + + add_custom_target(${TARGET}-msdk + DEPENDS ${TARGET} + COMMAND ${MAXIM_PATH}/Tools/OpenOCD/openocd -s ${MAXIM_PATH}/Tools/OpenOCD/scripts + -f interface/cmsis-dap.cfg -f target/max32690.cfg + -c "program $ verify; init; reset; exit" + VERBATIM + ) endfunction() diff --git a/hw/bsp/max32690/family.mk b/hw/bsp/max32690/family.mk index 0405a2914..8b9fbc175 100644 --- a/hw/bsp/max32690/family.mk +++ b/hw/bsp/max32690/family.mk @@ -14,9 +14,6 @@ PORT ?= 0 SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/GCC/startup_max32690.s LD_FILE = $(FAMILY_PATH)/max32690.ld -# IAR -SRC_S_IAR += $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/IAR/startup_max32690.s - # -------------- # Compiler Flags # -------------- @@ -49,7 +46,7 @@ LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs # For flash-jlink target JLINK_DEVICE = max32690 -# flash target using Jlik +# flash target using Jlink by default flash: flash-jlink # Optional flash option when running within an installed MSDK to use OpenOCD @@ -91,7 +88,6 @@ SRC_C += \ $(PERIPH_SRC)/UART/uart_me18.c \ $(PERIPH_SRC)/UART/uart_revb.c \ - INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ diff --git a/hw/bsp/max78002/README.md b/hw/bsp/max78002/README.md new file mode 100644 index 000000000..4fb1bede4 --- /dev/null +++ b/hw/bsp/max78002/README.md @@ -0,0 +1,28 @@ +# Analog Devices MAX78002 + +This BSP is for working with the Analog Devices +[MAX78002](https://www.analog.com/en/products/max78002.html) AI microcontroller. +The following boards are supported: + * [MAX78002EVKIT](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max78002evkit.html) + +This part family leverages the Maxim Microcontrollers SDK (MSDK) for the device +interfaces and hardware abstraction layers. This source code package is fetched +as part of the get-deps script. + +The microcontroller utilizes the standard GNU ARM toolchain. If this toolchain +is not already available on your build machine, it can be installed by using the +bundled MSDK installation. Details on downloading and installing can be found +in the [User's Guide](https://analogdevicesinc.github.io/msdk//USERGUIDE/). + +## Flashing + +The default flashing behavior in this BSP is to utilize JLink. This can be done +by running the `flash` or `flash-jlink` rule for Makefiles, or the +`-jlink` target for CMake. + +The Evaluation Kit is shipped with a CMSIS-DAP compatible debug probe. However, +at the time of writing, the necessary flashing algorithms for OpenOCD have not +yet been incorporated into the OpenOCD master branch. To utilize the provided +debug probes, please install the bundled MSDK package which includes the +appropriate OpenOCD modifications. To leverage this OpenOCD instance, run the +`flash-msdk` Makefile rule, or `-msdk` CMake target. diff --git a/hw/bsp/max78002/family.cmake b/hw/bsp/max78002/family.cmake index 28eaaa7e9..83fd3007f 100644 --- a/hw/bsp/max78002/family.cmake +++ b/hw/bsp/max78002/family.cmake @@ -42,7 +42,6 @@ function(add_board_target BOARD_TARGET) # Startup & Linker script set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX78002/Source/GCC/startup_max78002.S) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - #set(STARTUP_FILE_IAR ?) set(PERIPH_SRC ${MAX32_PERIPH}/Source) add_library(${BOARD_TARGET} STATIC @@ -87,8 +86,8 @@ function(add_board_target BOARD_TARGET) ) target_compile_options(${BOARD_TARGET} PRIVATE - -Wno-error=strict-prototypes - -Wno-error=redundant-decls + -Wno-error=strict-prototypes + -Wno-error=redundant-decls ) update_board(${BOARD_TARGET}) @@ -102,10 +101,6 @@ function(add_board_target BOARD_TARGET) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) endif () endfunction() @@ -146,8 +141,8 @@ function(family_configure_example TARGET RTOS) ) target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) target_compile_options(${TARGET}-tinyusb PRIVATE - -Wno-error=strict-prototypes - -Wno-error=redundant-decls + -Wno-error=strict-prototypes + -Wno-error=redundant-decls ) # Link dependencies @@ -155,4 +150,18 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_jlink(${TARGET}) + family_flash_msdk(${TARGET}) +endfunction() + +# Add flash msdk target +function(family_flash_msdk TARGET) + set(MAXIM_PATH "$ENV{MAXIM_PATH}") + + add_custom_target(${TARGET}-msdk + DEPENDS ${TARGET} + COMMAND ${MAXIM_PATH}/Tools/OpenOCD/openocd -s ${MAXIM_PATH}/Tools/OpenOCD/scripts + -f interface/cmsis-dap.cfg -f target/max78002.cfg + -c "program $ verify; init; reset; exit" + VERBATIM + ) endfunction() diff --git a/hw/bsp/max78002/family.mk b/hw/bsp/max78002/family.mk index 04163417c..8df8517da 100644 --- a/hw/bsp/max78002/family.mk +++ b/hw/bsp/max78002/family.mk @@ -14,9 +14,6 @@ PORT ?= 0 SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX78002/Source/GCC/startup_max78002.S LD_FILE = $(FAMILY_PATH)/max78002.ld -# IAR -#SRC_S_IAR += - # -------------- # Compiler Flags # -------------- @@ -45,7 +42,7 @@ LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs # For flash-jlink target JLINK_DEVICE = max78000 -# flash target using Jlik +# flash target using Jlink by default flash: flash-jlink # Optional flash option when running within an installed MSDK to use OpenOCD @@ -88,7 +85,6 @@ SRC_C += \ $(PERIPH_SRC)/UART/uart_ai87.c \ $(PERIPH_SRC)/UART/uart_revb.c \ - INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ -- cgit v1.3.1 From 494533f9d7b7961dd9a3acf7c2e9070f8ba172b5 Mon Sep 17 00:00:00 2001 From: Brent Kowal Date: Wed, 10 Jul 2024 15:52:43 -0400 Subject: Minor build system fix Correct a case-sensitive file extension issue in the MAX32690 build scripts. Did not present itself as an issue under MinGW or MSYS, just Linux. --- hw/bsp/max32690/family.cmake | 2 +- hw/bsp/max32690/family.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/bsp/max32690/family.cmake b/hw/bsp/max32690/family.cmake index 5c470f86b..d7a562956 100644 --- a/hw/bsp/max32690/family.cmake +++ b/hw/bsp/max32690/family.cmake @@ -44,7 +44,7 @@ function(add_board_target BOARD_TARGET) endif () # Startup & Linker script - set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX32690/Source/GCC/startup_max32690.s) + set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX32690/Source/GCC/startup_max32690.S) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(PERIPH_SRC ${MAX32_PERIPH}/Source) diff --git a/hw/bsp/max32690/family.mk b/hw/bsp/max32690/family.mk index 8b9fbc175..9360a07c6 100644 --- a/hw/bsp/max32690/family.mk +++ b/hw/bsp/max32690/family.mk @@ -11,7 +11,7 @@ CPU_CORE ?= cortex-m4 PORT ?= 0 # GCC -SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/GCC/startup_max32690.s +SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/GCC/startup_max32690.S LD_FILE = $(FAMILY_PATH)/max32690.ld # -------------- -- cgit v1.3.1 From 13f5f20c981cc54baa8438e275524db03fb79e94 Mon Sep 17 00:00:00 2001 From: Brent Kowal Date: Thu, 11 Jul 2024 12:13:30 -0400 Subject: Pre-commit fixes. Resolve codespell and EOF errors found in the pre-commit CI task. --- hw/bsp/max32650/README.md | 2 +- hw/bsp/max32650/boards/max32650evkit/max32650.ld | 2 +- hw/bsp/max32650/boards/max32650fthr/max32650.ld | 2 +- hw/bsp/max32650/boards/max32651evkit/max32651.ld | 2 +- hw/bsp/max32650/family.mk | 2 +- hw/bsp/max32666/family.c | 2 +- hw/bsp/max32666/max32666.ld | 2 +- hw/bsp/max32690/family.c | 2 +- hw/bsp/max32690/max32690.ld | 2 +- hw/bsp/max78002/family.c | 2 +- hw/bsp/max78002/max78002.ld | 4 ++-- src/portable/analog/max32/dcd_max32.c | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/hw/bsp/max32650/README.md b/hw/bsp/max32650/README.md index cb8069bba..ca66a1ac4 100644 --- a/hw/bsp/max32650/README.md +++ b/hw/bsp/max32650/README.md @@ -43,4 +43,4 @@ MAX32651EVKIT. To flash the signed image, the MSDK's OpenOCD variant must be used. To flash the MAX32651EVKIT please install the bundled MSDK, and utilize the `flash-msdk` -and `-msdk` rule and target. \ No newline at end of file +and `-msdk` rule and target. diff --git a/hw/bsp/max32650/boards/max32650evkit/max32650.ld b/hw/bsp/max32650/boards/max32650evkit/max32650.ld index 3a1e5100d..0e56a91ec 100644 --- a/hw/bsp/max32650/boards/max32650evkit/max32650.ld +++ b/hw/bsp/max32650/boards/max32650evkit/max32650.ld @@ -85,7 +85,7 @@ SECTIONS { { . = ALIGN(4); _bss = .; - *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM diff --git a/hw/bsp/max32650/boards/max32650fthr/max32650.ld b/hw/bsp/max32650/boards/max32650fthr/max32650.ld index 3a1e5100d..0e56a91ec 100644 --- a/hw/bsp/max32650/boards/max32650fthr/max32650.ld +++ b/hw/bsp/max32650/boards/max32650fthr/max32650.ld @@ -85,7 +85,7 @@ SECTIONS { { . = ALIGN(4); _bss = .; - *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM diff --git a/hw/bsp/max32650/boards/max32651evkit/max32651.ld b/hw/bsp/max32650/boards/max32651evkit/max32651.ld index a873463d4..3921d10f2 100644 --- a/hw/bsp/max32650/boards/max32651evkit/max32651.ld +++ b/hw/bsp/max32650/boards/max32651evkit/max32651.ld @@ -98,7 +98,7 @@ SECTIONS { { . = ALIGN(4); _bss = .; - *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM diff --git a/hw/bsp/max32650/family.mk b/hw/bsp/max32650/family.mk index 577d96717..0718523c3 100644 --- a/hw/bsp/max32650/family.mk +++ b/hw/bsp/max32650/family.mk @@ -121,7 +121,7 @@ SIGN_EXE := sign_app.exe endif endif -# Rule to sign the build. This will in-place modifiy the existing .elf file +# Rule to sign the build. This will in-place modify the existing .elf file # an populate the .sig section with the signature value sign-build: $(BUILD)/$(PROJECT).elf $(OBJCOPY) $(BUILD)/$(PROJECT).elf -R .sig -O binary $(BUILD)/$(PROJECT).bin diff --git a/hw/bsp/max32666/family.c b/hw/bsp/max32666/family.c index 98e1248d7..1398e09ff 100644 --- a/hw/bsp/max32666/family.c +++ b/hw/bsp/max32666/family.c @@ -106,7 +106,7 @@ uint32_t board_button_read(void) { size_t board_get_unique_id(uint8_t id[], size_t max_len) { uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN];//USN Buffer - /* All other 2nd parameter is optional checkum buffer */ + /* All other 2nd parameter is optional checksum buffer */ MXC_SYS_GetUSN(hw_id, NULL); size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN); diff --git a/hw/bsp/max32666/max32666.ld b/hw/bsp/max32666/max32666.ld index dcf61a3d0..06c124247 100644 --- a/hw/bsp/max32666/max32666.ld +++ b/hw/bsp/max32666/max32666.ld @@ -101,7 +101,7 @@ SECTIONS { { . = ALIGN(4); _bss = .; - *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM diff --git a/hw/bsp/max32690/family.c b/hw/bsp/max32690/family.c index acd6e2593..f4998bdbe 100644 --- a/hw/bsp/max32690/family.c +++ b/hw/bsp/max32690/family.c @@ -104,7 +104,7 @@ uint32_t board_button_read(void) { size_t board_get_unique_id(uint8_t id[], size_t max_len) { uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN];//USN Buffer - /* All other 2nd parameter is optional checkum buffer */ + /* All other 2nd parameter is optional checksum buffer */ MXC_SYS_GetUSN(hw_id, NULL); size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN); diff --git a/hw/bsp/max32690/max32690.ld b/hw/bsp/max32690/max32690.ld index 3d857b4e8..64b906a54 100644 --- a/hw/bsp/max32690/max32690.ld +++ b/hw/bsp/max32690/max32690.ld @@ -130,7 +130,7 @@ SECTIONS { { . = ALIGN(4); _bss = .; - *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM diff --git a/hw/bsp/max78002/family.c b/hw/bsp/max78002/family.c index c105f056b..7758083a2 100644 --- a/hw/bsp/max78002/family.c +++ b/hw/bsp/max78002/family.c @@ -103,7 +103,7 @@ uint32_t board_button_read(void) { size_t board_get_unique_id(uint8_t id[], size_t max_len) { uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN];//USN Buffer - /* All other 2nd parameter is optional checkum buffer */ + /* All other 2nd parameter is optional checksum buffer */ MXC_SYS_GetUSN(hw_id, NULL); size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN); diff --git a/hw/bsp/max78002/max78002.ld b/hw/bsp/max78002/max78002.ld index 60f99e28f..e5c4866ee 100644 --- a/hw/bsp/max78002/max78002.ld +++ b/hw/bsp/max78002/max78002.ld @@ -127,7 +127,7 @@ SECTIONS { { . = ALIGN(4); _bss = .; - *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM @@ -138,7 +138,7 @@ SECTIONS { _shared = .; *(.mailbox*) . = ALIGN(4); - *(.shared*) /*read-write zero initialized data: uninitialzed global variable*/ + *(.shared*) /*read-write zero initialized data: uninitialized global variable*/ _eshared = ALIGN(., 4); } > SRAM __shared_data = LOADADDR(.shared); diff --git a/src/portable/analog/max32/dcd_max32.c b/src/portable/analog/max32/dcd_max32.c index 7226003de..df616120a 100644 --- a/src/portable/analog/max32/dcd_max32.c +++ b/src/portable/analog/max32/dcd_max32.c @@ -196,7 +196,7 @@ static bool handle_xfer_in(uint_fast8_t ep_addr) { } pipe->remaining = rem - len; } - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_INPKTRDY;//TODO: Verify a | isnt needed + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_INPKTRDY;//TODO: Verify a | isn't needed return false; } -- cgit v1.3.1 From 1f590c36287e26b6d189bf41f9b7704e957bf8af Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 12 Jul 2024 16:53:21 +0700 Subject: - add tud_cdc_configure_fifo() to replace CFG_TUD_CDC_PERSISTENT_TX_BUFF - new line, and code format --- src/class/cdc/cdc_device.c | 237 ++++++++++++++++++--------------------------- src/class/cdc/cdc_device.h | 195 ++++++++++++++----------------------- 2 files changed, 168 insertions(+), 264 deletions(-) diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index f36725eba..681a1b852 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -45,8 +45,7 @@ //--------------------------------------------------------------------+ #define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -typedef struct -{ +typedef struct { uint8_t itf_num; uint8_t ep_notif; uint8_t ep_in; @@ -56,7 +55,7 @@ typedef struct uint8_t line_state; /*------------- From this point, data is not cleared by bus reset -------------*/ - char wanted_char; + char wanted_char; TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding; // FIFO @@ -72,18 +71,17 @@ typedef struct // Endpoint Transfer buffer CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EP_BUFSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EP_BUFSIZE]; - -}cdcd_interface_t; +} cdcd_interface_t; #define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char) //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -CFG_TUD_MEM_SECTION tu_static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; +CFG_TUD_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; +static tud_cdc_configure_fifo_t _cdcd_fifo_cfg; -static bool _prep_out_transaction (cdcd_interface_t* p_cdc) -{ +static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { uint8_t const rhport = 0; uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff); @@ -99,14 +97,11 @@ static bool _prep_out_transaction (cdcd_interface_t* p_cdc) // fifo can be changed before endpoint is claimed available = tu_fifo_remaining(&p_cdc->rx_ff); - if ( available >= sizeof(p_cdc->epout_buf) ) - { + if ( available >= sizeof(p_cdc->epout_buf) ) { return usbd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, sizeof(p_cdc->epout_buf)); - }else - { + }else { // Release endpoint since we don't make any transfer usbd_edpt_release(rhport, p_cdc->ep_out); - return false; } } @@ -114,51 +109,49 @@ static bool _prep_out_transaction (cdcd_interface_t* p_cdc) //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ -bool tud_cdc_n_connected(uint8_t itf) -{ + +bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg) { + TU_VERIFY(cfg); + _cdcd_fifo_cfg = (*cfg); + return true; +} + +bool tud_cdc_n_connected(uint8_t itf) { // DTR (bit 0) active is considered as connected return tud_ready() && tu_bit_test(_cdcd_itf[itf].line_state, 0); } -uint8_t tud_cdc_n_get_line_state (uint8_t itf) -{ +uint8_t tud_cdc_n_get_line_state(uint8_t itf) { return _cdcd_itf[itf].line_state; } -void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding) -{ +void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t* coding) { (*coding) = _cdcd_itf[itf].line_coding; } -void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted) -{ +void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) { _cdcd_itf[itf].wanted_char = wanted; } - //--------------------------------------------------------------------+ // READ API //--------------------------------------------------------------------+ -uint32_t tud_cdc_n_available(uint8_t itf) -{ +uint32_t tud_cdc_n_available(uint8_t itf) { return tu_fifo_count(&_cdcd_itf[itf].rx_ff); } -uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) -{ +uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); _prep_out_transaction(p_cdc); return num_read; } -bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) -{ +bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) { return tu_fifo_peek(&_cdcd_itf[itf].rx_ff, chr); } -void tud_cdc_n_read_flush (uint8_t itf) -{ +void tud_cdc_n_read_flush(uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; tu_fifo_clear(&p_cdc->rx_ff); _prep_out_transaction(p_cdc); @@ -167,16 +160,15 @@ void tud_cdc_n_read_flush (uint8_t itf) //--------------------------------------------------------------------+ // WRITE API //--------------------------------------------------------------------+ -uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) -{ +uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; uint16_t ret = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); // flush if queue more than packet size - if ( tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE - #if CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE - || tu_fifo_full(&p_cdc->tx_ff) // check full if fifo size is less than packet size - #endif + if (tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE + #if CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE + || tu_fifo_full(&p_cdc->tx_ff) // check full if fifo size is less than packet size + #endif ) { tud_cdc_n_write_flush(itf); } @@ -184,30 +176,27 @@ uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) return ret; } -uint32_t tud_cdc_n_write_flush (uint8_t itf) -{ +uint32_t tud_cdc_n_write_flush(uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; // Skip if usb is not ready yet - TU_VERIFY( tud_ready(), 0 ); + TU_VERIFY(tud_ready(), 0); // No data to send - if ( !tu_fifo_count(&p_cdc->tx_ff) ) return 0; + if (!tu_fifo_count(&p_cdc->tx_ff)) return 0; uint8_t const rhport = 0; // Claim the endpoint - TU_VERIFY( usbd_edpt_claim(rhport, p_cdc->ep_in), 0 ); + TU_VERIFY(usbd_edpt_claim(rhport, p_cdc->ep_in), 0); // Pull data from FIFO uint16_t const count = tu_fifo_read_n(&p_cdc->tx_ff, p_cdc->epin_buf, sizeof(p_cdc->epin_buf)); - if ( count ) - { - TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0 ); + if (count) { + TU_ASSERT(usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0); return count; - }else - { + } else { // Release endpoint since we don't make any transfer // Note: data is dropped if terminal is not connected usbd_edpt_release(rhport, p_cdc->ep_in); @@ -215,33 +204,30 @@ uint32_t tud_cdc_n_write_flush (uint8_t itf) } } -uint32_t tud_cdc_n_write_available (uint8_t itf) -{ +uint32_t tud_cdc_n_write_available(uint8_t itf) { return tu_fifo_remaining(&_cdcd_itf[itf].tx_ff); } -bool tud_cdc_n_write_clear (uint8_t itf) -{ +bool tud_cdc_n_write_clear(uint8_t itf) { return tu_fifo_clear(&_cdcd_itf[itf].tx_ff); } //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void cdcd_init(void) -{ +void cdcd_init(void) { tu_memclr(_cdcd_itf, sizeof(_cdcd_itf)); + tu_memclr(&_cdcd_fifo_cfg, sizeof(_cdcd_fifo_cfg)); - for(uint8_t i=0; iwanted_char = (char) -1; // default line coding is : stop bit = 1, parity = none, data bits = 8 - p_cdc->line_coding.bit_rate = 115200; + p_cdc->line_coding.bit_rate = 115200; p_cdc->line_coding.stop_bits = 0; - p_cdc->line_coding.parity = 0; + p_cdc->line_coding.parity = 0; p_cdc->line_coding.data_bits = 8; // Config RX fifo @@ -285,35 +271,28 @@ bool cdcd_deinit(void) { return true; } -void cdcd_reset(uint8_t rhport) -{ +void cdcd_reset(uint8_t rhport) { (void) rhport; - for(uint8_t i=0; irx_ff); - #if !CFG_TUD_CDC_PERSISTENT_TX_BUFF - tu_fifo_clear(&p_cdc->tx_ff); - #endif + if (!_cdcd_fifo_cfg.rx_persistent) tu_fifo_clear(&p_cdc->rx_ff); + if (!_cdcd_fifo_cfg.tx_persistent) tu_fifo_clear(&p_cdc->tx_ff); tu_fifo_set_overwritable(&p_cdc->tx_ff, true); } } -uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) -{ +uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { // Only support ACM subclass TU_VERIFY( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, 0); // Find available interface - cdcd_interface_t * p_cdc = NULL; - for(uint8_t cdc_id=0; cdc_iditf_num = itf_desc->bInterfaceNumber; uint16_t drv_len = sizeof(tusb_desc_interface_t); - uint8_t const * p_desc = tu_desc_next( itf_desc ); + uint8_t const* p_desc = tu_desc_next(itf_desc); // Communication Functional Descriptors - while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len ) - { + while (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len) { drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + p_desc = tu_desc_next(p_desc); } - if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) - { + if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { // notification endpoint - tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; + tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const*) p_desc; - TU_ASSERT( usbd_edpt_open(rhport, desc_ep), 0 ); + TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); p_cdc->ep_notif = desc_ep->bEndpointAddress; drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + p_desc = tu_desc_next(p_desc); } //------------- Data Interface (if any) -------------// - if ( (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && - (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) ) - { + if ((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && + (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const*) p_desc)->bInterfaceClass)) { // next to endpoint descriptor drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + p_desc = tu_desc_next(p_desc); // Open endpoint pair - TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in), 0 ); + TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in), 0); - drv_len += 2*sizeof(tusb_desc_endpoint_t); + drv_len += 2 * sizeof(tusb_desc_endpoint_t); } // Prepare for incoming data @@ -368,8 +344,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) -bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) -{ +bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { // Handle class request only TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); @@ -377,42 +352,33 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t cdcd_interface_t* p_cdc = _cdcd_itf; // Identify which interface to use - for ( ; ; itf++, p_cdc++) - { + for (;; itf++, p_cdc++) { if (itf >= TU_ARRAY_SIZE(_cdcd_itf)) return false; - if ( p_cdc->itf_num == request->wIndex ) break; + if (p_cdc->itf_num == request->wIndex) break; } - switch ( request->bRequest ) - { + switch (request->bRequest) { case CDC_REQUEST_SET_LINE_CODING: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_LOG_DRV(" Set Line Coding\r\n"); tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); + } else if (stage == CONTROL_STAGE_ACK) { + if (tud_cdc_line_coding_cb) tud_cdc_line_coding_cb(itf, &p_cdc->line_coding); } - else if ( stage == CONTROL_STAGE_ACK) - { - if ( tud_cdc_line_coding_cb ) tud_cdc_line_coding_cb(itf, &p_cdc->line_coding); - } - break; + break; case CDC_REQUEST_GET_LINE_CODING: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_LOG_DRV(" Get Line Coding\r\n"); tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); } - break; + break; case CDC_REQUEST_SET_CONTROL_LINE_STATE: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { tud_control_status(rhport, request); - } - else if (stage == CONTROL_STAGE_ACK) - { + } else if (stage == CONTROL_STAGE_ACK) { // CDC PSTN v1.2 section 6.3.12 // Bit 0: Indicates if DTE is present or not. // This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR (Data Terminal Ready) @@ -429,61 +395,54 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); // Invoke callback - if ( tud_cdc_line_state_cb ) tud_cdc_line_state_cb(itf, dtr, rts); + if (tud_cdc_line_state_cb) tud_cdc_line_state_cb(itf, dtr, rts); } - break; + break; + case CDC_REQUEST_SEND_BREAK: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { tud_control_status(rhport, request); - } - else if (stage == CONTROL_STAGE_ACK) - { + } else if (stage == CONTROL_STAGE_ACK) { TU_LOG_DRV(" Send Break\r\n"); - if ( tud_cdc_send_break_cb ) tud_cdc_send_break_cb(itf, request->wValue); + if (tud_cdc_send_break_cb) tud_cdc_send_break_cb(itf, request->wValue); } - break; + break; - default: return false; // stall unsupported request + default: + return false; // stall unsupported request } return true; } -bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ +bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; uint8_t itf; cdcd_interface_t* p_cdc; // Identify which interface to use - for (itf = 0; itf < CFG_TUD_CDC; itf++) - { + for (itf = 0; itf < CFG_TUD_CDC; itf++) { p_cdc = &_cdcd_itf[itf]; - if ( ( ep_addr == p_cdc->ep_out ) || ( ep_addr == p_cdc->ep_in ) ) break; + if ((ep_addr == p_cdc->ep_out) || (ep_addr == p_cdc->ep_in)) break; } TU_ASSERT(itf < CFG_TUD_CDC); // Received new data - if ( ep_addr == p_cdc->ep_out ) - { + if (ep_addr == p_cdc->ep_out) { tu_fifo_write_n(&p_cdc->rx_ff, p_cdc->epout_buf, (uint16_t) xferred_bytes); // Check for wanted char and invoke callback if needed - if ( tud_cdc_rx_wanted_cb && (((signed char) p_cdc->wanted_char) != -1) ) - { - for ( uint32_t i = 0; i < xferred_bytes; i++ ) - { - if ( (p_cdc->wanted_char == p_cdc->epout_buf[i]) && !tu_fifo_empty(&p_cdc->rx_ff) ) - { + if (tud_cdc_rx_wanted_cb && (((signed char) p_cdc->wanted_char) != -1)) { + for (uint32_t i = 0; i < xferred_bytes; i++) { + if ((p_cdc->wanted_char == p_cdc->epout_buf[i]) && !tu_fifo_empty(&p_cdc->rx_ff)) { tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); } } } // invoke receive callback (if there is still data) - if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff) ) tud_cdc_rx_cb(itf); + if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff)) tud_cdc_rx_cb(itf); // prepare for OUT transaction _prep_out_transaction(p_cdc); @@ -492,19 +451,15 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // Data sent to host, we continue to fetch from tx fifo to send. // Note: This will cause incorrect baudrate set in line coding. // Though maybe the baudrate is not really important !!! - if ( ep_addr == p_cdc->ep_in ) - { + if (ep_addr == p_cdc->ep_in) { // invoke transmit callback to possibly refill tx fifo - if ( tud_cdc_tx_complete_cb ) tud_cdc_tx_complete_cb(itf); + if (tud_cdc_tx_complete_cb) tud_cdc_tx_complete_cb(itf); - if ( 0 == tud_cdc_n_write_flush(itf) ) - { + if (0 == tud_cdc_n_write_flush(itf)) { // If there is no data left, a ZLP should be sent if // xferred_bytes is multiple of EP Packet size and not zero - if ( !tu_fifo_count(&p_cdc->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE-1))) ) - { - if ( usbd_edpt_claim(rhport, p_cdc->ep_in) ) - { + if (!tu_fifo_count(&p_cdc->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE - 1)))) { + if (usbd_edpt_claim(rhport, p_cdc->ep_in)) { usbd_edpt_xfer(rhport, p_cdc->ep_in, NULL, 0); } } diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index db709b3bc..5c2d07c5b 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_CDC_DEVICE_H_ -#define _TUSB_CDC_DEVICE_H_ +#ifndef TUSB_CDC_DEVICE_H_ +#define TUSB_CDC_DEVICE_H_ #include "cdc.h" @@ -41,213 +41,162 @@ #define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #endif -// By default the TX fifo buffer is cleared on connect / bus reset. -// Enable this to persist any data in the fifo instead. -#ifndef CFG_TUD_CDC_PERSISTENT_TX_BUFF - #define CFG_TUD_CDC_PERSISTENT_TX_BUFF (0) -#endif - #ifdef __cplusplus extern "C" { #endif -/** \addtogroup CDC_Serial Serial - * @{ - * \defgroup CDC_Serial_Device Device - * @{ */ +//--------------------------------------------------------------------+ +// Driver Configuration +//--------------------------------------------------------------------+ + +typedef struct TU_ATTR_PACKED { + uint8_t rx_persistent : 1; // keep rx fifo on bus reset or disconnect + uint8_t tx_persistent : 1; // keep tx fifo on bus reset or disconnect +} tud_cdc_configure_fifo_t; + +// Configure CDC FIFOs behavior +bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg); //--------------------------------------------------------------------+ -// Application API (Multiple Ports) -// CFG_TUD_CDC > 1 +// Application API (Multiple Ports) i.e CFG_TUD_CDC > 1 //--------------------------------------------------------------------+ // Check if terminal is connected to this port -bool tud_cdc_n_connected (uint8_t itf); +bool tud_cdc_n_connected(uint8_t itf); // Get current line state. Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send) -uint8_t tud_cdc_n_get_line_state (uint8_t itf); +uint8_t tud_cdc_n_get_line_state(uint8_t itf); // Get current line encoding: bit rate, stop bits parity etc .. -void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding); +void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t* coding); // Set special character that will trigger tud_cdc_rx_wanted_cb() callback on receiving -void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted); +void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted); // Get the number of bytes available for reading -uint32_t tud_cdc_n_available (uint8_t itf); +uint32_t tud_cdc_n_available(uint8_t itf); // Read received bytes -uint32_t tud_cdc_n_read (uint8_t itf, void* buffer, uint32_t bufsize); +uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize); // Read a byte, return -1 if there is none -static inline -int32_t tud_cdc_n_read_char (uint8_t itf); +TU_ATTR_ALWAYS_INLINE static inline int32_t tud_cdc_n_read_char(uint8_t itf) { + uint8_t ch; + return tud_cdc_n_read(itf, &ch, 1) ? (int32_t) ch : -1; +} // Clear the received FIFO -void tud_cdc_n_read_flush (uint8_t itf); +void tud_cdc_n_read_flush(uint8_t itf); // Get a byte from FIFO without removing it -bool tud_cdc_n_peek (uint8_t itf, uint8_t* ui8); +bool tud_cdc_n_peek(uint8_t itf, uint8_t* ui8); // Write bytes to TX FIFO, data may remain in the FIFO for a while -uint32_t tud_cdc_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); +uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize); // Write a byte -static inline -uint32_t tud_cdc_n_write_char (uint8_t itf, char ch); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_n_write_char(uint8_t itf, char ch) { + return tud_cdc_n_write(itf, &ch, 1); +} // Write a null-terminated string -static inline -uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_n_write_str(uint8_t itf, char const* str) { + return tud_cdc_n_write(itf, str, strlen(str)); +} // Force sending data if possible, return number of forced bytes -uint32_t tud_cdc_n_write_flush (uint8_t itf); +uint32_t tud_cdc_n_write_flush(uint8_t itf); // Return the number of bytes (characters) available for writing to TX FIFO buffer in a single n_write operation. -uint32_t tud_cdc_n_write_available (uint8_t itf); +uint32_t tud_cdc_n_write_available(uint8_t itf); // Clear the transmit FIFO -bool tud_cdc_n_write_clear (uint8_t itf); +bool tud_cdc_n_write_clear(uint8_t itf); //--------------------------------------------------------------------+ // Application API (Single Port) //--------------------------------------------------------------------+ -static inline bool tud_cdc_connected (void); -static inline uint8_t tud_cdc_get_line_state (void); -static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding); -static inline void tud_cdc_set_wanted_char (char wanted); - -static inline uint32_t tud_cdc_available (void); -static inline int32_t tud_cdc_read_char (void); -static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize); -static inline void tud_cdc_read_flush (void); -static inline bool tud_cdc_peek (uint8_t* ui8); - -static inline uint32_t tud_cdc_write_char (char ch); -static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize); -static inline uint32_t tud_cdc_write_str (char const* str); -static inline uint32_t tud_cdc_write_flush (void); -static inline uint32_t tud_cdc_write_available (void); -static inline bool tud_cdc_write_clear (void); - -//--------------------------------------------------------------------+ -// Application Callback API (weak is optional) -//--------------------------------------------------------------------+ - -// Invoked when received new data -TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf); - -// Invoked when received `wanted_char` -TU_ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char); - -// Invoked when a TX is complete and therefore space becomes available in TX buffer -TU_ATTR_WEAK void tud_cdc_tx_complete_cb(uint8_t itf); - -// Invoked when line state DTR & RTS are changed via SET_CONTROL_LINE_STATE -TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts); - -// Invoked when line coding is change via SET_LINE_CODING -TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding); - -// Invoked when received send break -TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms); - -//--------------------------------------------------------------------+ -// Inline Functions -//--------------------------------------------------------------------+ -static inline int32_t tud_cdc_n_read_char (uint8_t itf) -{ - uint8_t ch; - return tud_cdc_n_read(itf, &ch, 1) ? (int32_t) ch : -1; -} - -static inline uint32_t tud_cdc_n_write_char(uint8_t itf, char ch) -{ - return tud_cdc_n_write(itf, &ch, 1); -} - -static inline uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str) -{ - return tud_cdc_n_write(itf, str, strlen(str)); -} - -static inline bool tud_cdc_connected (void) -{ +TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_connected(void) { return tud_cdc_n_connected(0); } -static inline uint8_t tud_cdc_get_line_state (void) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_cdc_get_line_state(void) { return tud_cdc_n_get_line_state(0); } -static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding) -{ +TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_get_line_coding(cdc_line_coding_t* coding) { tud_cdc_n_get_line_coding(0, coding); } -static inline void tud_cdc_set_wanted_char (char wanted) -{ +TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_set_wanted_char(char wanted) { tud_cdc_n_set_wanted_char(0, wanted); } -static inline uint32_t tud_cdc_available (void) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_available(void) { return tud_cdc_n_available(0); } -static inline int32_t tud_cdc_read_char (void) -{ +TU_ATTR_ALWAYS_INLINE static inline int32_t tud_cdc_read_char(void) { return tud_cdc_n_read_char(0); } -static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_read(void* buffer, uint32_t bufsize) { return tud_cdc_n_read(0, buffer, bufsize); } -static inline void tud_cdc_read_flush (void) -{ +TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_read_flush(void) { tud_cdc_n_read_flush(0); } -static inline bool tud_cdc_peek (uint8_t* ui8) -{ +TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_peek(uint8_t* ui8) { return tud_cdc_n_peek(0, ui8); } -static inline uint32_t tud_cdc_write_char (char ch) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_char(char ch) { return tud_cdc_n_write_char(0, ch); } -static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write(void const* buffer, uint32_t bufsize) { return tud_cdc_n_write(0, buffer, bufsize); } -static inline uint32_t tud_cdc_write_str (char const* str) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_str(char const* str) { return tud_cdc_n_write_str(0, str); } -static inline uint32_t tud_cdc_write_flush (void) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_flush(void) { return tud_cdc_n_write_flush(0); } -static inline uint32_t tud_cdc_write_available(void) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_available(void) { return tud_cdc_n_write_available(0); } -static inline bool tud_cdc_write_clear(void) -{ +TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_write_clear(void) { return tud_cdc_n_write_clear(0); } -/** @} */ -/** @} */ +//--------------------------------------------------------------------+ +// Application Callback API (weak is optional) +//--------------------------------------------------------------------+ + +// Invoked when received new data +TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf); + +// Invoked when received `wanted_char` +TU_ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char); + +// Invoked when a TX is complete and therefore space becomes available in TX buffer +TU_ATTR_WEAK void tud_cdc_tx_complete_cb(uint8_t itf); + +// Invoked when line state DTR & RTS are changed via SET_CONTROL_LINE_STATE +TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts); + +// Invoked when line coding is change via SET_LINE_CODING +TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding); + +// Invoked when received send break +TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms); //--------------------------------------------------------------------+ // INTERNAL USBD-CLASS DRIVER API -- cgit v1.3.1 From ef71093046c948973ff3c9bc316ca7195686835d Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 12 Jul 2024 17:20:06 +0700 Subject: add lsusb for hil pi4 --- .github/workflows/hil_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index 39a9060a2..d5bd9c200 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -132,9 +132,9 @@ jobs: # USB bus on rpi4 is not stable, reset it before testing - name: Reset USB bus run: | - # lsusb -t # reset VIA Labs 2.0 hub sudo usbreset 001/002 + lsusb -t - name: Checkout TinyUSB uses: actions/checkout@v4 -- cgit v1.3.1 From 4ce1cce40a01dce56cab2c73745f4f2c9d212b25 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 12 Jul 2024 20:17:14 +0700 Subject: simplify dwc2 test mode - all dwc2 ip seems to support test mode in both fs/hs -> remove TUP_USBIP_DWC2_TEST_MODE - remove dcd_check_test_mode_support(), all should be supported - move enum tusb_feature_test_mode_t to tusb_types.h --- src/common/tusb_mcu.h | 3 -- src/common/tusb_types.h | 9 ++++++ src/device/dcd.h | 13 +------- src/device/usbd.c | 56 +++++++++++------------------------ src/portable/synopsys/dwc2/dcd_dwc2.c | 20 +++---------- src/tusb_option.h | 2 +- 6 files changed, 32 insertions(+), 71 deletions(-) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 80826c895..637281bfc 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -195,7 +195,6 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32F4) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 - #define TUP_USBIP_DWC2_TEST_MODE // For most mcu, FS has 4, HS has 6. TODO 446/469/479 HS has 9 #define TUP_DCD_ENDPOINT_MAX 6 @@ -210,7 +209,6 @@ // MCU with on-chip HS Phy #if defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F733xx) #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS - #define TUP_USBIP_DWC2_TEST_MODE #endif #elif TU_CHECK_MCU(OPT_MCU_STM32H7) @@ -285,7 +283,6 @@ defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) #define TUP_DCD_ENDPOINT_MAX 9 #define TUP_RHPORT_HIGHSPEED 1 - #define TUP_USBIP_DWC2_TEST_MODE #else #define TUP_DCD_ENDPOINT_MAX 6 #endif diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index b571f9b72..1501a5af6 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -214,6 +214,15 @@ enum { #define TUSB_DESC_CONFIG_POWER_MA(x) ((x)/2) +// USB 2.0 Spec Table 9-7: Test Mode Selectors +typedef enum { + TUSB_FEATURE_TEST_J = 1, + TUSB_FEATURE_TEST_K, + TUSB_FEATURE_TEST_SE0_NAK, + TUSB_FEATURE_TEST_PACKET, + TUSB_FEATURE_TEST_FORCE_ENABLE, +} tusb_feature_test_mode_t; + //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ diff --git a/src/device/dcd.h b/src/device/dcd.h index f6735b077..5356e9be1 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -89,14 +89,6 @@ typedef struct TU_ATTR_ALIGNED(4) { }; } dcd_event_t; -typedef enum { - TEST_J = 1, - TEST_K, - TEST_SE0_NAK, - TEST_PACKET, - TEST_FORCE_ENABLE, -} test_mode_t; - //TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct"); //--------------------------------------------------------------------+ @@ -150,11 +142,8 @@ void dcd_disconnect(uint8_t rhport); void dcd_sof_enable(uint8_t rhport, bool en); #if CFG_TUD_TEST_MODE -// Check if the test mode is supported, returns true is test mode selector is supported -bool dcd_check_test_mode_support(test_mode_t test_selector) TU_ATTR_WEAK; - // Put device into a test mode (needs power cycle to quit) -void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) TU_ATTR_WEAK; +void dcd_enter_test_mode(uint8_t rhport, tusb_feature_test_mode_t test_selector); #endif //--------------------------------------------------------------------+ // Endpoint API diff --git a/src/device/usbd.c b/src/device/usbd.c index 800d9c824..4105a71a4 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -321,9 +321,17 @@ TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request); static bool process_set_config(uint8_t rhport, uint8_t cfg_num); static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request); + #if CFG_TUD_TEST_MODE -static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { + TU_VERIFY(CONTROL_STAGE_ACK == stage); + uint8_t const selector = tu_u16_high(request->wIndex); + TU_LOG_USBD(" Enter Test Mode (test selector index: %d)\r\n", selector); + dcd_enter_test_mode(rhport, (tusb_feature_test_mode_t) selector); + return true; +} #endif + // from usbd_control.c void usbd_control_reset(void); void usbd_control_set_request(tusb_control_request_t const *request); @@ -695,7 +703,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const } if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) { - // Non standard request is not supported + // Non-standard request is not supported TU_BREAKPOINT(); return false; } @@ -759,43 +767,27 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const break; case TUSB_REQ_SET_FEATURE: - // Handle the feature selector - switch(p_request->wValue) - { - // Support for remote wakeup + switch(p_request->wValue) { case TUSB_REQ_FEATURE_REMOTE_WAKEUP: TU_LOG_USBD(" Enable Remote Wakeup\r\n"); - // Host may enable remote wake up before suspending especially HID device _usbd_dev.remote_wakeup_en = true; tud_control_status(rhport, p_request); break; -#if CFG_TUD_TEST_MODE - // Support for TEST_MODE + #if CFG_TUD_TEST_MODE case TUSB_REQ_FEATURE_TEST_MODE: { // Only handle the test mode if supported and valid - TU_VERIFY(dcd_enter_test_mode && dcd_check_test_mode_support && 0 == tu_u16_low(p_request->wIndex)); - - uint8_t selector = tu_u16_high(p_request->wIndex); - - // Stall request if the selected test mode isn't supported - if (!dcd_check_test_mode_support((test_mode_t)selector)) - { - TU_LOG_USBD(" Unsupported Test Mode (test selector index: %d)\r\n", selector); + TU_VERIFY(0 == tu_u16_low(p_request->wIndex)); - return false; - } - - // Acknowledge request - tud_control_status(rhport, p_request); - - TU_LOG_USBD(" Enter Test Mode (test selector index: %d)\r\n", selector); + uint8_t const selector = tu_u16_high(p_request->wIndex); + TU_VERIFY(TUSB_FEATURE_TEST_J <= selector && selector <= TUSB_FEATURE_TEST_FORCE_ENABLE); usbd_control_set_complete_callback(process_test_mode_cb); + tud_control_status(rhport, p_request); break; } -#endif /* CFG_TUD_TEST_MODE */ + #endif /* CFG_TUD_TEST_MODE */ // Stall unsupported feature selector default: return false; @@ -1127,20 +1119,6 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const } } -#if CFG_TUD_TEST_MODE -static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) -{ - // At this point it should already be ensured that dcd_enter_test_mode() is defined - - // Only enter the test mode after the request for it has completed - TU_VERIFY(CONTROL_STAGE_ACK == stage); - - dcd_enter_test_mode(rhport, (test_mode_t)tu_u16_high(request->wIndex)); - - return true; -} -#endif /* CFG_TUD_TEST_MODE */ - //--------------------------------------------------------------------+ // DCD Event Handler //--------------------------------------------------------------------+ diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index dbcd586c5..9a38b46dc 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1195,25 +1195,13 @@ void dcd_int_handler(uint8_t rhport) { // } } -#if defined(TUP_USBIP_DWC2_TEST_MODE) && CFG_TUD_TEST_MODE - -bool dcd_check_test_mode_support(test_mode_t test_selector) { - // Check if test mode selector is unsupported - if (TEST_FORCE_ENABLE < test_selector || TEST_J > test_selector) { - return false; - } - - return true; -} - -void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) { - // Get port address... +#if CFG_TUD_TEST_MODE +void dcd_enter_test_mode(uint8_t rhport, tusb_feature_test_mode_t test_selector) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Enable the test mode - dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (test_selector << DCTL_TCTL_Pos); + dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (((uint8_t) test_selector) << DCTL_TCTL_Pos); } - -#endif /* TUP_USBIP_DWC2_TEST_MODE && CFG_TUD_TEST_MODE */ +#endif #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 8990cf92b..f2cc284dc 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -381,7 +381,7 @@ #error "CFG_TUD_ENDPPOINT_MAX must be less than or equal to TUP_DCD_ENDPOINT_MAX" #endif -// USB 2.0 compliance test mode support +// USB 2.0 7.1.20: compliance test mode support #ifndef CFG_TUD_TEST_MODE #define CFG_TUD_TEST_MODE 0 #endif -- cgit v1.3.1 From cc6806144fa0ff4fba4d63c8ec2cc580bb4db48a Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Jul 2024 17:46:20 +0700 Subject: update hil test to run on new pi5 --- .github/workflows/hil_test.yml | 35 +++++++++++++++++++---------------- test/hil/hil_test.py | 4 +++- test/hil/pi4.json | 37 ------------------------------------- test/hil/rpi.json | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 54 deletions(-) delete mode 100644 test/hil/pi4.json create mode 100644 test/hil/rpi.json diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index d5bd9c200..51227d408 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -17,6 +17,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +env: + HIL_JSON: test/hil/rpi.json + jobs: # --------------------------------------- # Build Non Espressif @@ -36,7 +39,7 @@ jobs: sudo apt install -y jq # Non-Espresif boards - BOARDS_LIST=$(jq -r '.boards[] | select(.flasher != "esptool") | "-b " + .name' test/hil/pi4.json | tr '\n' ' ') + BOARDS_LIST=$(jq -r '.boards[] | select(.flasher != "esptool") | "-b " + .name' ${{ env.HIL_JSON }} | tr '\n' ' ') echo "BOARDS_LIST=$BOARDS_LIST" echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT @@ -57,7 +60,7 @@ jobs: - name: Upload Artifacts for Hardware Testing uses: actions/upload-artifact@v4 with: - name: hil_pi4 + name: hil_rpi path: | cmake-build/cmake-build-*/*/*/*.elf cmake-build/cmake-build-*/*/*/*.bin @@ -78,7 +81,7 @@ jobs: run: | sudo apt install -y jq # Espressif boards - BOARDS_LIST=$(jq -r '.boards[] | select(.flasher == "esptool") | "-b " + .name' test/hil/pi4.json | tr '\n' ' ') + BOARDS_LIST=$(jq -r '.boards[] | select(.flasher == "esptool") | "-b " + .name' ${{ env.HIL_JSON }} | tr '\n' ' ') echo "BOARDS_LIST=$BOARDS_LIST" echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT @@ -102,7 +105,7 @@ jobs: - name: Upload Artifacts for Hardware Testing uses: actions/upload-artifact@v4 with: - name: hil_pi4_esp + name: hil_rpi_esp path: | cmake-build/cmake-build-*/*/*/*.bin cmake-build/cmake-build-*/*/*/bootloader/bootloader.bin @@ -112,14 +115,14 @@ jobs: # --------------------------------------- # Hardware in the loop (HIL) - # Current self-hosted instance is running on an RPI4. For attached hardware checkout test/hil/pi4.json + # self-hosted running on an RPI. For attached hardware checkout test/hil/rpi.json # --------------------------------------- - hil-pi4: + hil-rpi: if: github.repository_owner == 'hathach' needs: - build - build-esp - runs-on: [self-hosted, rp2040, nrf52840, esp32s3, hardware-in-the-loop] + runs-on: [self-hosted, ARM64, rpi, hardware-in-the-loop] env: BOARDS_LIST: "${{ needs.build.outputs.BOARDS_LIST }} ${{ needs.build-esp.outputs.BOARDS_LIST }}" steps: @@ -129,12 +132,12 @@ jobs: rm -rf "${{ github.workspace }}" mkdir -p "${{ github.workspace }}" - # USB bus on rpi4 is not stable, reset it before testing - - name: Reset USB bus - run: | - # reset VIA Labs 2.0 hub - sudo usbreset 001/002 - lsusb -t + # USB bus on rpi is not stable, reset it before testing +# - name: Reset USB bus +# run: | +# # reset VIA Labs 2.0 hub +# sudo usbreset 001/002 +# lsusb -t - name: Checkout TinyUSB uses: actions/checkout@v4 @@ -144,13 +147,13 @@ jobs: - name: Download Artifacts uses: actions/download-artifact@v4 with: - name: hil_pi4 + name: hil_rpi path: cmake-build - name: Download Artifacts uses: actions/download-artifact@v4 with: - name: hil_pi4_esp + name: hil_rpi_esp path: cmake-build - name: Test on actual hardware @@ -159,4 +162,4 @@ jobs: echo "::group::{cmake-build contents}" tree cmake-build echo "::endgroup::" - python3 test/hil/hil_test.py $BOARDS_LIST pi4.json + python3 test/hil/hil_test.py $BOARDS_LIST ${{ env.HIL_JSON }} diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index c2699cc6f..3ba84f881 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -330,7 +330,9 @@ def main(): config_file = args.config_file boards = args.board - config_file = os.path.join(os.path.dirname(__file__), config_file) + # if config file is not found, try to find it in the same directory as this script + if not os.path.exists(config_file): + config_file = os.path.join(os.path.dirname(__file__), config_file) with open(config_file) as f: config = json.load(f) diff --git a/test/hil/pi4.json b/test/hil/pi4.json deleted file mode 100644 index bdb8a5fa5..000000000 --- a/test/hil/pi4.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "boards": [ - { - "name": "raspberry_pi_pico", - "uid": "E6614C311B764A37", - "flasher": "openocd", - "flasher_sn": "E6614103E72C1D2F", - "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"" - }, - { - "name": "feather_nrf52840_express", - "uid": "1F0479CD0F764471", - "flasher": "jlink", - "flasher_sn": "000682804350", - "flasher_args": "-device nrf52840_xxaa" - }, - { - "name": "itsybitsy_m4", - "uid": "D784B28C5338533335202020FF044726", - "flasher": "bossac", - "flashser_vendor": "Adafruit Industries", - "flasher_product": "ItsyBitsy M4 Express", - "flasher_reset_pin": "2", - "flasher_args": "--offset 0x4000" - }, - { - "name": "espressif_s3_devkitm", - "uid": "84F703C084E4", - "tests": [ - "cdc_msc_freertos", "hid_composite_freertos" - ], - "flasher": "esptool", - "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", - "flasher_args": "-b 1500000" - } - ] -} diff --git a/test/hil/rpi.json b/test/hil/rpi.json new file mode 100644 index 000000000..bdb8a5fa5 --- /dev/null +++ b/test/hil/rpi.json @@ -0,0 +1,37 @@ +{ + "boards": [ + { + "name": "raspberry_pi_pico", + "uid": "E6614C311B764A37", + "flasher": "openocd", + "flasher_sn": "E6614103E72C1D2F", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"" + }, + { + "name": "feather_nrf52840_express", + "uid": "1F0479CD0F764471", + "flasher": "jlink", + "flasher_sn": "000682804350", + "flasher_args": "-device nrf52840_xxaa" + }, + { + "name": "itsybitsy_m4", + "uid": "D784B28C5338533335202020FF044726", + "flasher": "bossac", + "flashser_vendor": "Adafruit Industries", + "flasher_product": "ItsyBitsy M4 Express", + "flasher_reset_pin": "2", + "flasher_args": "--offset 0x4000" + }, + { + "name": "espressif_s3_devkitm", + "uid": "84F703C084E4", + "tests": [ + "cdc_msc_freertos", "hid_composite_freertos" + ], + "flasher": "esptool", + "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", + "flasher_args": "-b 1500000" + } + ] +} -- cgit v1.3.1 From 5edc8458f2db7bd24fa3767e652632227833535f Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Jul 2024 14:30:51 +0700 Subject: hil flash itsybitsy m4 with picoprobe --- test/hil/hil_test.py | 24 +++++++++++++----------- test/hil/rpi.json | 8 +++----- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 3ba84f881..f571e6e02 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -114,11 +114,10 @@ def read_disk_file(id, fname): # Flashing firmware # ------------------------------------------------------------- def run_cmd(cmd): - # print(cmd) + #print(cmd) r = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - title = 'command error' if r.returncode != 0: - # print build output if failed + title = 'command error' if os.getenv('CI'): print(f"::group::{title}") print(r.stdout.decode("utf-8")) @@ -156,23 +155,23 @@ def flash_esptool(board, firmware): return ret -def doublereset_with_rpi_gpio(board): +def doublereset_with_rpi_gpio(pin): # Off = 0 = Reset - led = gpiozero.LED(board["flasher_reset_pin"]) + nrst = gpiozero.LED(pin) - led.off() + nrst.off() time.sleep(0.1) - led.on() + nrst.on() time.sleep(0.1) - led.off() + nrst.off() time.sleep(0.1) - led.on() + nrst.on() def flash_bossac(board, firmware): # double reset to enter bootloader if platform.machine() == 'aarch64': - doublereset_with_rpi_gpio(board) + doublereset_with_rpi_gpio(board["flasher_reset_pin"]) port = get_serial_dev(board["uid"], board["flashser_vendor"], board["flasher_product"], 0) timeout = ENUM_TIMEOUT @@ -367,7 +366,10 @@ def main(): test_list.remove(skip) for test in test_list: - fw_name = f'cmake-build/cmake-build-{name}/device/{test}/{test}' + fw_dir = f'cmake-build/cmake-build-{name}/device/{test}' + if not os.path.exists(fw_dir): + fw_dir = f'examples/cmake-build-{name}/device/{test}' + fw_name = f'{fw_dir}/{test}' print(f' {test} ...', end='') # flash firmware. It may fail randomly, retry a few times diff --git a/test/hil/rpi.json b/test/hil/rpi.json index bdb8a5fa5..c9a77936d 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -17,11 +17,9 @@ { "name": "itsybitsy_m4", "uid": "D784B28C5338533335202020FF044726", - "flasher": "bossac", - "flashser_vendor": "Adafruit Industries", - "flasher_product": "ItsyBitsy M4 Express", - "flasher_reset_pin": "2", - "flasher_args": "--offset 0x4000" + "flasher": "openocd", + "flasher_sn": "E6614C311B597D32", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/atsame5x.cfg -c \"adapter speed 5000\"" }, { "name": "espressif_s3_devkitm", -- cgit v1.3.1 From 0ecf15bc61b2684e53250437d295d6c43682a724 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Jul 2024 14:35:23 +0700 Subject: follow up to #2253 - rename tud_hid_report_fail_cb() to tud_hid_report_failed_cb() and change its signature - use default implementation for hid callbacks to be compatible with keil compiler - code format --- src/class/cdc/cdc_device.h | 2 +- src/class/hid/hid_device.c | 268 +++++++++++++++++++++++---------------------- src/class/hid/hid_device.h | 106 +++++++----------- 3 files changed, 180 insertions(+), 196 deletions(-) diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 5c2d07c5b..34670517a 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -58,7 +58,7 @@ typedef struct TU_ATTR_PACKED { bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg); //--------------------------------------------------------------------+ -// Application API (Multiple Ports) i.e CFG_TUD_CDC > 1 +// Application API (Multiple Ports) i.e. CFG_TUD_CDC > 1 //--------------------------------------------------------------------+ // Check if terminal is connected to this port diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index ada01582e..7168ab3d5 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -61,28 +61,53 @@ typedef struct { CFG_TUD_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID]; /*------------- Helpers -------------*/ -static inline uint8_t get_index_by_itfnum(uint8_t itf_num) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t get_index_by_itfnum(uint8_t itf_num) { for (uint8_t i = 0; i < CFG_TUD_HID; i++) { - if (itf_num == _hidd_itf[i].itf_num) + if (itf_num == _hidd_itf[i].itf_num) { return i; + } } - return 0xFF; } +//--------------------------------------------------------------------+ +// Weak stubs: invoked if no strong implementation is available +//--------------------------------------------------------------------+ +TU_ATTR_WEAK void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol) { + (void) instance; + (void) protocol; +} + +TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate) { + (void) instance; + (void) idle_rate; + return true; +} + +TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) { + (void) instance; + (void) report; + (void) len; +} + +// Invoked when a transfer wasn't successful +TU_ATTR_WEAK void tud_hid_report_failed_cb(uint8_t instance, hid_report_type_t report_type, uint8_t const* report, uint16_t xferred_bytes) { + (void) instance; + (void) report_type; + (void) report; + (void) xferred_bytes; +} + //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ -bool tud_hid_n_ready(uint8_t instance) -{ +bool tud_hid_n_ready(uint8_t instance) { uint8_t const rhport = 0; uint8_t const ep_in = _hidd_itf[instance].ep_in; return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(rhport, ep_in); } -bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const *report, uint16_t len) -{ +bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const *report, uint16_t len) { uint8_t const rhport = 0; hidd_interface_t *p_hid = &_hidd_itf[instance]; @@ -101,14 +126,16 @@ bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const *report, u return usbd_edpt_xfer(rhport, p_hid->ep_in, p_hid->epin_buf, len); } -uint8_t tud_hid_n_interface_protocol(uint8_t instance) { return _hidd_itf[instance].itf_protocol; } +uint8_t tud_hid_n_interface_protocol(uint8_t instance) { + return _hidd_itf[instance].itf_protocol; +} -uint8_t tud_hid_n_get_protocol(uint8_t instance) { return _hidd_itf[instance].protocol_mode; } +uint8_t tud_hid_n_get_protocol(uint8_t instance) { + return _hidd_itf[instance].protocol_mode; +} -bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) -{ +bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) { hid_keyboard_report_t report; - report.modifier = modifier; report.reserved = 0; @@ -121,8 +148,8 @@ bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modi return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } -bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) -{ +bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, + uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) { hid_mouse_report_t report = { .buttons = buttons, .x = x, @@ -134,8 +161,8 @@ bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } -bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) -{ +bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, + uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) { hid_abs_mouse_report_t report = { .buttons = buttons, .x = x, @@ -146,8 +173,8 @@ bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t but return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } -bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) -{ +bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, + int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) { hid_gamepad_report_t report = { .x = x, .y = y, @@ -165,28 +192,25 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int //--------------------------------------------------------------------+ // USBD-CLASS API //--------------------------------------------------------------------+ -void hidd_init(void) -{ +void hidd_init(void) { hidd_reset(0); } -bool hidd_deinit(void) -{ +bool hidd_deinit(void) { return true; } -void hidd_reset(uint8_t rhport) -{ +void hidd_reset(uint8_t rhport) { (void)rhport; tu_memclr(_hidd_itf, sizeof(_hidd_itf)); } -uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16_t max_len) -{ +uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0); // len = interface + hid + n*endpoints - uint16_t const drv_len = (uint16_t)(sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); + uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(max_len >= drv_len, 0); // Find available interface @@ -211,8 +235,9 @@ uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16 p_desc = tu_desc_next(p_desc); TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, desc_itf->bNumEndpoints, TUSB_XFER_INTERRUPT, &p_hid->ep_out, &p_hid->ep_in), 0); - if (desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT) + if (desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT) { p_hid->itf_protocol = desc_itf->bInterfaceProtocol; + } p_hid->protocol_mode = HID_PROTOCOL_REPORT; // Per Specs: default is report mode p_hid->itf_num = desc_itf->bInterfaceNumber; @@ -234,8 +259,7 @@ uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16 // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) -bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) -{ +bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); uint8_t const hid_itf = get_index_by_itfnum((uint8_t)request->wIndex); @@ -262,90 +286,82 @@ bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t } else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) { //------------- Class Specific Request -------------// switch (request->bRequest) { - case HID_REQ_CONTROL_GET_REPORT: - if (stage == CONTROL_STAGE_SETUP) { - uint8_t const report_type = tu_u16_high(request->wValue); - uint8_t const report_id = tu_u16_low(request->wValue); - - uint8_t *report_buf = p_hid->ctrl_buf; - uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); - - uint16_t xferlen = 0; - - // If host request a specific Report ID, add ID to as 1 byte of response - if ((report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1)) { - *report_buf++ = report_id; - req_len--; - - xferlen++; + case HID_REQ_CONTROL_GET_REPORT: + if (stage == CONTROL_STAGE_SETUP) { + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); + + uint8_t* report_buf = p_hid->ctrl_buf; + uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); + uint16_t xferlen = 0; + + // If host request a specific Report ID, add ID to as 1 byte of response + if ((report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1)) { + *report_buf++ = report_id; + req_len--; + xferlen++; + } + + xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, req_len); + TU_ASSERT(xferlen > 0); + + tud_control_xfer(rhport, request, p_hid->ctrl_buf, xferlen); } - - xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t)report_type, report_buf, req_len); - TU_ASSERT(xferlen > 0); - - tud_control_xfer(rhport, request, p_hid->ctrl_buf, xferlen); - } - break; - - case HID_REQ_CONTROL_SET_REPORT: - if (stage == CONTROL_STAGE_SETUP) { - TU_VERIFY(request->wLength <= sizeof(p_hid->ctrl_buf)); - tud_control_xfer(rhport, request, p_hid->ctrl_buf, request->wLength); - } else if (stage == CONTROL_STAGE_ACK) { - uint8_t const report_type = tu_u16_high(request->wValue); - uint8_t const report_id = tu_u16_low(request->wValue); - - uint8_t const *report_buf = p_hid->ctrl_buf; - uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); - - // If host request a specific Report ID, extract report ID in buffer before invoking callback - if ((report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0])) { - report_buf++; - report_len--; + break; + + case HID_REQ_CONTROL_SET_REPORT: + if (stage == CONTROL_STAGE_SETUP) { + TU_VERIFY(request->wLength <= sizeof(p_hid->ctrl_buf)); + tud_control_xfer(rhport, request, p_hid->ctrl_buf, request->wLength); + } else if (stage == CONTROL_STAGE_ACK) { + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); + + uint8_t const* report_buf = p_hid->ctrl_buf; + uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); + + // If host request a specific Report ID, extract report ID in buffer before invoking callback + if ((report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0])) { + report_buf++; + report_len--; + } + + tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, report_len); } + break; - tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t)report_type, report_buf, report_len); - } - break; - - case HID_REQ_CONTROL_SET_IDLE: - if (stage == CONTROL_STAGE_SETUP) { - p_hid->idle_rate = tu_u16_high(request->wValue); - if (tud_hid_set_idle_cb) { - // stall request if callback return false - TU_VERIFY(tud_hid_set_idle_cb(hid_itf, p_hid->idle_rate)); + case HID_REQ_CONTROL_SET_IDLE: + if (stage == CONTROL_STAGE_SETUP) { + p_hid->idle_rate = tu_u16_high(request->wValue); + TU_VERIFY(tud_hid_set_idle_cb(hid_itf, p_hid->idle_rate)); // stall if false + tud_control_status(rhport, request); } + break; - tud_control_status(rhport, request); - } - break; - - case HID_REQ_CONTROL_GET_IDLE: - if (stage == CONTROL_STAGE_SETUP) { - // TODO idle rate of report - tud_control_xfer(rhport, request, &p_hid->idle_rate, 1); - } - break; + case HID_REQ_CONTROL_GET_IDLE: + if (stage == CONTROL_STAGE_SETUP) { + // TODO idle rate of report + tud_control_xfer(rhport, request, &p_hid->idle_rate, 1); + } + break; - case HID_REQ_CONTROL_GET_PROTOCOL: - if (stage == CONTROL_STAGE_SETUP) { - tud_control_xfer(rhport, request, &p_hid->protocol_mode, 1); - } - break; + case HID_REQ_CONTROL_GET_PROTOCOL: + if (stage == CONTROL_STAGE_SETUP) { + tud_control_xfer(rhport, request, &p_hid->protocol_mode, 1); + } + break; - case HID_REQ_CONTROL_SET_PROTOCOL: - if (stage == CONTROL_STAGE_SETUP) { - tud_control_status(rhport, request); - } else if (stage == CONTROL_STAGE_ACK) { - p_hid->protocol_mode = (uint8_t)request->wValue; - if (tud_hid_set_protocol_cb) { + case HID_REQ_CONTROL_SET_PROTOCOL: + if (stage == CONTROL_STAGE_SETUP) { + tud_control_status(rhport, request); + } else if (stage == CONTROL_STAGE_ACK) { + p_hid->protocol_mode = (uint8_t) request->wValue; tud_hid_set_protocol_cb(hid_itf, p_hid->protocol_mode); } - } - break; + break; - default: - return false; // stall unsupported request + default: + return false; // stall unsupported request } } else { return false; // stall unsupported request @@ -354,45 +370,35 @@ bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t return true; } -bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ - (void)result; - +bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { uint8_t instance = 0; hidd_interface_t *p_hid = _hidd_itf; // Identify which interface to use for (instance = 0; instance < CFG_TUD_HID; instance++) { p_hid = &_hidd_itf[instance]; - if ((ep_addr == p_hid->ep_out) || (ep_addr == p_hid->ep_in)) + if ((ep_addr == p_hid->ep_out) || (ep_addr == p_hid->ep_in)) { break; + } } TU_ASSERT(instance < CFG_TUD_HID); - // Check if there was a problem - if (XFER_RESULT_SUCCESS != result) { // Inform application about the issue - if (tud_hid_report_fail_cb) { - tud_hid_report_fail_cb(instance, ep_addr, (uint16_t)xferred_bytes); + if (ep_addr == p_hid->ep_in) { + // Input report + if (XFER_RESULT_SUCCESS == result) { + tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t) xferred_bytes); + } else { + tud_hid_report_failed_cb(instance, HID_REPORT_TYPE_INPUT, p_hid->epin_buf, (uint16_t) xferred_bytes); } - - // Allow a new transfer to be received if issue happened on an OUT endpoint - if (ep_addr == p_hid->ep_out) { - // Prepare the OUT endpoint to be able to receive a new transfer - TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); + } else { + // Output report + if (XFER_RESULT_SUCCESS == result) { + tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t)xferred_bytes); + } else { + tud_hid_report_failed_cb(instance, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t) xferred_bytes); } - return true; - } - - // Sent report successfully - if (ep_addr == p_hid->ep_in) { - if (tud_hid_report_complete_cb) { - tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t)xferred_bytes); - } - } - // Received report successfully - else if (ep_addr == p_hid->ep_out) { - tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t)xferred_bytes); + // prepare for new transfer TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); } diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index fcbf161c4..89c28e061 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_HID_DEVICE_H_ -#define _TUSB_HID_DEVICE_H_ +#ifndef TUSB_HID_DEVICE_H_ +#define TUSB_HID_DEVICE_H_ #include "hid.h" @@ -48,8 +48,7 @@ #endif //--------------------------------------------------------------------+ -// Application API (Multiple Instances) -// CFG_TUD_HID > 1 +// Application API (Multiple Instances) i.e. CFG_TUD_HID > 1 //--------------------------------------------------------------------+ // Check if the interface is ready to use @@ -76,12 +75,6 @@ bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons // use template layout report as defined by hid_abs_mouse_report_t bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal); - -static inline bool tud_hid_abs_mouse_report(uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) -{ - return tud_hid_n_abs_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); -} - // Gamepad: convenient helper to send gamepad report if application // use template layout report TUD_HID_REPORT_DESC_GAMEPAD bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons); @@ -89,16 +82,40 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int //--------------------------------------------------------------------+ // Application API (Single Port) //--------------------------------------------------------------------+ -static inline bool tud_hid_ready(void); -static inline uint8_t tud_hid_interface_protocol(void); -static inline uint8_t tud_hid_get_protocol(void); -static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len); -static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]); -static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal); -static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons); +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_ready(void) { + return tud_hid_n_ready(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_hid_interface_protocol(void) { + return tud_hid_n_interface_protocol(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_hid_get_protocol(void) { + return tud_hid_n_get_protocol(0); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len) { + return tud_hid_n_report(0, report_id, report, len); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) { + return tud_hid_n_keyboard_report(0, report_id, modifier, keycode); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) { + return tud_hid_n_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_abs_mouse_report(uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) { + return tud_hid_n_abs_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) { + return tud_hid_n_gamepad_report(0, report_id, x, y, z, rz, rx, ry, hat, buttons); +} //--------------------------------------------------------------------+ -// Callbacks (Weak is optional) +// Application Callbacks //--------------------------------------------------------------------+ // Invoked when received GET HID REPORT DESCRIPTOR request @@ -111,63 +128,25 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance); uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen); // Invoked when received SET_REPORT control request or -// received data on OUT endpoint ( Report ID = 0, Type = 0 ) +// received data on OUT endpoint (Report ID = 0, Type = OUTPUT) void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize); // Invoked when received SET_PROTOCOL request // protocol is either HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) -TU_ATTR_WEAK void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol); +void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol); // Invoked when received SET_IDLE request. return false will stall the request -// - Idle Rate = 0 : only send report if there is changes, i.e skip duplication +// - Idle Rate = 0 : only send report if there is changes, i.e. skip duplication // - Idle Rate > 0 : skip duplication, but send at least 1 report every idle rate (in unit of 4 ms). -TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); +bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); // Invoked when a transfer wasn't successful -TU_ATTR_WEAK void tud_hid_report_fail_cb(uint8_t instance, uint8_t ep_addr, uint16_t len); - -//--------------------------------------------------------------------+ -// Inline Functions -//--------------------------------------------------------------------+ -static inline bool tud_hid_ready(void) -{ - return tud_hid_n_ready(0); -} - -static inline uint8_t tud_hid_interface_protocol(void) -{ - return tud_hid_n_interface_protocol(0); -} - -static inline uint8_t tud_hid_get_protocol(void) -{ - return tud_hid_n_get_protocol(0); -} - -static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len) -{ - return tud_hid_n_report(0, report_id, report, len); -} - -static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) -{ - return tud_hid_n_keyboard_report(0, report_id, modifier, keycode); -} - -static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) -{ - return tud_hid_n_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); -} - -static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) -{ - return tud_hid_n_gamepad_report(0, report_id, x, y, z, rz, rx, ry, hat, buttons); -} +void tud_hid_report_failed_cb(uint8_t instance, hid_report_type_t report_type, uint8_t const* report, uint16_t xferred_bytes); /* --------------------------------------------------------------------+ * HID Report Descriptor Template @@ -645,9 +624,8 @@ uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool hidd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); - #ifdef __cplusplus } #endif -#endif /* _TUSB_HID_DEVICE_H_ */ +#endif -- cgit v1.3.1 From 57a08200fc19bf49cf2c497011e88e83c3cbf249 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Jul 2024 19:28:59 +0700 Subject: add family cmake/make for da1469x boards --- .idea/cmake.xml | 7 +- .../build_system/cmake/cpu/cortex-m33-nodsp.cmake | 25 ++ hw/bsp/da14695_dk_usb/board.mk | 56 ---- hw/bsp/da14695_dk_usb/da14695_dk_usb.c | 134 --------- hw/bsp/da14695_dk_usb/da1469x.ld | 244 ----------------- hw/bsp/da14695_dk_usb/gcc_startup_da1469x.S | 301 --------------------- hw/bsp/da14695_dk_usb/product_header.dump | Bin 8192 -> 0 bytes hw/bsp/da14695_dk_usb/syscfg/syscfg.h | 34 --- hw/bsp/da1469x/boards/da14695_dk_usb/board.cmake | 4 + hw/bsp/da1469x/boards/da14695_dk_usb/board.h | 10 + hw/bsp/da1469x/boards/da14695_dk_usb/board.mk | 1 + .../da1469x/boards/da14695_dk_usb/syscfg/syscfg.h | 34 +++ hw/bsp/da1469x/boards/da1469x_dk_pro/board.cmake | 4 + hw/bsp/da1469x/boards/da1469x_dk_pro/board.h | 12 + hw/bsp/da1469x/boards/da1469x_dk_pro/board.mk | 2 + .../da1469x/boards/da1469x_dk_pro/syscfg/syscfg.h | 34 +++ hw/bsp/da1469x/family.c | 142 ++++++++++ hw/bsp/da1469x/family.cmake | 141 ++++++++++ hw/bsp/da1469x/family.mk | 62 +++++ hw/bsp/da1469x/gcc_startup_da1469x.S | 301 +++++++++++++++++++++ hw/bsp/da1469x/linker/da1469x.ld | 244 +++++++++++++++++ hw/bsp/da1469x/product_header.dump | Bin 0 -> 8192 bytes hw/bsp/da1469x_dk_pro/board.mk | 56 ---- hw/bsp/da1469x_dk_pro/da1469x-dk-pro.c | 151 ----------- hw/bsp/da1469x_dk_pro/da1469x.ld | 244 ----------------- hw/bsp/da1469x_dk_pro/gcc_startup_da1469x.S | 301 --------------------- hw/bsp/da1469x_dk_pro/product_header.dump | Bin 8192 -> 0 bytes hw/bsp/da1469x_dk_pro/syscfg/syscfg.h | 34 --- 28 files changed, 1020 insertions(+), 1558 deletions(-) create mode 100644 examples/build_system/cmake/cpu/cortex-m33-nodsp.cmake delete mode 100644 hw/bsp/da14695_dk_usb/board.mk delete mode 100644 hw/bsp/da14695_dk_usb/da14695_dk_usb.c delete mode 100644 hw/bsp/da14695_dk_usb/da1469x.ld delete mode 100644 hw/bsp/da14695_dk_usb/gcc_startup_da1469x.S delete mode 100644 hw/bsp/da14695_dk_usb/product_header.dump delete mode 100644 hw/bsp/da14695_dk_usb/syscfg/syscfg.h create mode 100644 hw/bsp/da1469x/boards/da14695_dk_usb/board.cmake create mode 100644 hw/bsp/da1469x/boards/da14695_dk_usb/board.h create mode 100644 hw/bsp/da1469x/boards/da14695_dk_usb/board.mk create mode 100644 hw/bsp/da1469x/boards/da14695_dk_usb/syscfg/syscfg.h create mode 100644 hw/bsp/da1469x/boards/da1469x_dk_pro/board.cmake create mode 100644 hw/bsp/da1469x/boards/da1469x_dk_pro/board.h create mode 100644 hw/bsp/da1469x/boards/da1469x_dk_pro/board.mk create mode 100644 hw/bsp/da1469x/boards/da1469x_dk_pro/syscfg/syscfg.h create mode 100644 hw/bsp/da1469x/family.c create mode 100644 hw/bsp/da1469x/family.cmake create mode 100644 hw/bsp/da1469x/family.mk create mode 100644 hw/bsp/da1469x/gcc_startup_da1469x.S create mode 100644 hw/bsp/da1469x/linker/da1469x.ld create mode 100644 hw/bsp/da1469x/product_header.dump delete mode 100644 hw/bsp/da1469x_dk_pro/board.mk delete mode 100644 hw/bsp/da1469x_dk_pro/da1469x-dk-pro.c delete mode 100644 hw/bsp/da1469x_dk_pro/da1469x.ld delete mode 100644 hw/bsp/da1469x_dk_pro/gcc_startup_da1469x.S delete mode 100644 hw/bsp/da1469x_dk_pro/product_header.dump delete mode 100644 hw/bsp/da1469x_dk_pro/syscfg/syscfg.h diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 1055e31d3..ec900b4a6 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -3,7 +3,7 @@ - + @@ -67,7 +67,7 @@ - + @@ -134,9 +134,10 @@ - + + \ No newline at end of file diff --git a/examples/build_system/cmake/cpu/cortex-m33-nodsp.cmake b/examples/build_system/cmake/cpu/cortex-m33-nodsp.cmake new file mode 100644 index 000000000..b3cd743fd --- /dev/null +++ b/examples/build_system/cmake/cpu/cortex-m33-nodsp.cmake @@ -0,0 +1,25 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mthumb + -mcpu=cortex-m33+nodsp + -mfloat-abi=hard + -mfpu=fpv5-sp-d16 + ) + set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m33+nodsp + -mfpu=fpv5-sp-d16 + ) + set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + set(TOOLCHAIN_COMMON_FLAGS + --cpu cortex-m33+nodsp + --fpu VFPv5-SP + ) + set(FREERTOS_PORT IAR_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") + +endif () diff --git a/hw/bsp/da14695_dk_usb/board.mk b/hw/bsp/da14695_dk_usb/board.mk deleted file mode 100644 index 980b1a361..000000000 --- a/hw/bsp/da14695_dk_usb/board.mk +++ /dev/null @@ -1,56 +0,0 @@ -MCU_FAMILY_DIR = hw/mcu/dialog/da1469x - -CFLAGS += \ - -flto \ - -mthumb \ - -mthumb-interwork \ - -mabi=aapcs \ - -mcpu=cortex-m33+nodsp \ - -mfloat-abi=hard \ - -mfpu=fpv5-sp-d16 \ - -nostdlib \ - -DCORE_M33 \ - -DCFG_TUSB_MCU=OPT_MCU_DA1469X \ - -DCFG_TUD_ENDPOINT0_SIZE=8\ - -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs - -# All source paths should be relative to the top level. -LD_FILE = hw/bsp/$(BOARD)/da1469x.ld - -# While this is for da1469x chip, there is chance that da1468x chip family will also work -SRC_C += \ - src/portable/dialog/da146xx/dcd_da146xx.c \ - $(MCU_FAMILY_DIR)/src/system_da1469x.c \ - $(MCU_FAMILY_DIR)/src/da1469x_clock.c \ - $(MCU_FAMILY_DIR)/src/hal_gpio.c \ - -SRC_S += hw/bsp/$(BOARD)/gcc_startup_da1469x.S - -INC += \ - $(TOP)/hw/bsp/$(BOARD) \ - $(TOP)/$(MCU_FAMILY_DIR)/include \ - $(TOP)/$(MCU_FAMILY_DIR)/SDK_10.0.8.105/sdk/bsp/include - -# For freeRTOS port source -FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM33_NTZ/non_secure - -# For flash-jlink target -JLINK_DEVICE = DA14695 - -# flash using jlink but with some twists -flash: flash-dialog - -flash-dialog: $(BUILD)/$(PROJECT).bin - @echo '#define SW_VERSION "v_1.0.0.1"' >$(BUILD)/version.h - @echo '#define SW_VERSION_DATE "'`date +"%Y-%m-%d %H:%M"`'"' >>$(BUILD)/version.h - mkimage da1469x $(BUILD)/$(PROJECT).bin $(BUILD)/version.h $^.img - cp $(TOP)/hw/bsp/$(BOARD)/product_header.dump $(BUILD)/$(BOARD)-image.bin - cat $^.img >> $(BUILD)/$(BOARD)-image.bin - @echo r > $(BUILD)/$(BOARD).jlink - @echo halt >> $(BUILD)/$(BOARD).jlink - @echo loadfile $(BUILD)/$(BOARD)-image.bin 0x16000000 >> $(BUILD)/$(BOARD).jlink - @echo r >> $(BUILD)/$(BOARD).jlink - @echo go >> $(BUILD)/$(BOARD).jlink - @echo exit >> $(BUILD)/$(BOARD).jlink - $(JLINKEXE) -device $(JLINK_DEVICE) -if $(JLINK_IF) -JTAGConf -1,-1 -speed auto -CommandFile $(BUILD)/$(BOARD).jlink diff --git a/hw/bsp/da14695_dk_usb/da14695_dk_usb.c b/hw/bsp/da14695_dk_usb/da14695_dk_usb.c deleted file mode 100644 index 667b83de3..000000000 --- a/hw/bsp/da14695_dk_usb/da14695_dk_usb.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Jerzy Kasenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "bsp/board_api.h" -#include -#include - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB_IRQHandler(void) -{ - tud_int_handler(0); -} - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM -//--------------------------------------------------------------------+ - -#define LED_PIN 33 // P1.1 -#define LED_STATE_ON 1 -#define LED_STATE_OFF (1-LED_STATE_ON) - -#define BUTTON_PIN 6 - -void UnhandledIRQ(void) -{ - CRG_TOP->SYS_CTRL_REG = 0x80; - __BKPT(1); - while(1); -} - -// DA146xx driver function that must be called whenever VBUS changes. -extern void tusb_vbus_changed(bool present); - -void board_init(void) -{ - // LED - hal_gpio_init_out(LED_PIN, LED_STATE_ON); - - hal_gpio_init_out(1, 0); - hal_gpio_init_out(2, 0); - hal_gpio_init_out(3, 0); - hal_gpio_init_out(4, 0); - hal_gpio_init_out(5, 0); - - // Button - hal_gpio_init_in(BUTTON_PIN, HAL_GPIO_PULL_DOWN); - - // 1ms tick timer - SysTick_Config(SystemCoreClock / 1000); - -#if CFG_TUD_ENABLED - // This board is USB powered there is no need to monitor - // VBUS line. Notify driver that VBUS is present. - tusb_vbus_changed(true); - - /* Setup USB IRQ */ - NVIC_SetPriority(USB_IRQn, 2); - NVIC_EnableIRQ(USB_IRQn); - - /* Use PLL96 / 2 clock not HCLK */ - CRG_TOP->CLK_CTRL_REG &= ~CRG_TOP_CLK_CTRL_REG_USB_CLK_SRC_Msk; - - mcu_gpio_set_pin_function(14, MCU_GPIO_MODE_INPUT, MCU_GPIO_FUNC_USB); - mcu_gpio_set_pin_function(15, MCU_GPIO_MODE_INPUT, MCU_GPIO_FUNC_USB); -#endif -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) -{ - hal_gpio_write(LED_PIN, state ? LED_STATE_ON : LED_STATE_OFF); -} - -uint32_t board_button_read(void) -{ - // button is active HIGH - return hal_gpio_read(BUTTON_PIN); -} - -int board_uart_read(uint8_t* buf, int len) -{ - (void)buf; - (void)len; - return 0; -} - -int board_uart_write(void const * buf, int len) -{ - (void)buf; - (void)len; - - return 0; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; -void SysTick_Handler(void) -{ - system_ticks++; -} - -uint32_t board_millis(void) -{ - return system_ticks; -} -#endif diff --git a/hw/bsp/da14695_dk_usb/da1469x.ld b/hw/bsp/da14695_dk_usb/da1469x.ld deleted file mode 100644 index 8cc1d9d99..000000000 --- a/hw/bsp/da14695_dk_usb/da1469x.ld +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -MEMORY -{ - /* - * Flash is remapped at 0x0 by 1st stage bootloader, but this is done with - * an offset derived from image header thus it is safer to use remapped - * address space at 0x0 instead of QSPI_M address space at 0x16000000. - * Bootloader partition is 32K, but 9K is currently reserved for product - * header (8K) and image header (1K). - * First 512 bytes of SYSRAM are remapped at 0x0 and used as ISR vector - * (there's no need to reallocate ISR vector) and thus cannot be used by - * application. - */ - - FLASH (r) : ORIGIN = (0x00000000), LENGTH = (1024 * 1024) - RAM (rw) : ORIGIN = (0x20000000), LENGTH = (512 * 1024) -} - -OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") - -/* Linker script to place sections and symbol values. Should be used together - * with other linker script that defines memory regions FLASH and RAM. - * It references following symbols, which must be defined in code: - * Reset_Handler : Entry of reset handler - * - * It defines following symbols, which code can use without definition: - * __exidx_start - * __exidx_end - * __etext - * __data_start__ - * __preinit_array_start - * __preinit_array_end - * __init_array_start - * __init_array_end - * __fini_array_start - * __fini_array_end - * __data_end__ - * __bss_start__ - * __bss_end__ - * __HeapBase - * __HeapLimit - * __StackLimit - * __StackTop - * __stack - * __bssnz_start__ - * __bssnz_end__ - */ -ENTRY(Reset_Handler) - -SECTIONS -{ - __text = .; - - .text : - { - __isr_vector_start = .; - KEEP(*(.isr_vector)) - /* ISR vector shall have exactly 512 bytes */ - . = __isr_vector_start + 0x200; - __isr_vector_end = .; - - *(.text) - *(.text.*) - - *(.libcmac.rom) - - KEEP(*(.init)) - KEEP(*(.fini)) - - /* .ctors */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - - /* .dtors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - *(.rodata*) - - *(.eh_frame*) - . = ALIGN(4); - } > FLASH - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - . = ALIGN(4); - } > FLASH - - __exidx_start = .; - .ARM : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - . = ALIGN(4); - } > FLASH - __exidx_end = .; - - .intvect : - { - . = ALIGN(4); - __intvect_start__ = .; - . = . + (__isr_vector_end - __isr_vector_start); - . = ALIGN(4); - } > RAM - - .sleep_state (NOLOAD) : - { - . = ALIGN(4); - *(sleep_state) - } > RAM - - /* This section will be zeroed by RTT package init */ - .rtt (NOLOAD): - { - . = ALIGN(4); - *(.rtt) - . = ALIGN(4); - } > RAM - - __text_ram_addr = LOADADDR(.text_ram); - - .text_ram : - { - . = ALIGN(4); - __text_ram_start__ = .; - *(.text_ram*) - . = ALIGN(4); - __text_ram_end__ = .; - } > RAM AT > FLASH - - __etext = LOADADDR(.data); - - .data : - { - __data_start__ = .; - *(vtable) - *(.data*) - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - *(.preinit_array) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - *(SORT(.init_array.*)) - *(.init_array) - PROVIDE_HIDDEN (__init_array_end = .); - - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - *(SORT(.fini_array.*)) - *(.fini_array) - PROVIDE_HIDDEN (__fini_array_end = .); - - *(.jcr) - . = ALIGN(4); - /* All data end */ - __data_end__ = .; - } > RAM AT > FLASH - - .bssnz : - { - . = ALIGN(4); - __bssnz_start__ = .; - *(.bss.core.nz*) - . = ALIGN(4); - __bssnz_end__ = .; - } > RAM - - .bss : - { - . = ALIGN(4); - __bss_start__ = .; - *(.bss*) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .cmac (NOLOAD) : - { - . = ALIGN(0x400); - *(.libcmac.ram) - } > RAM - - /* Heap starts after BSS */ - . = ALIGN(8); - __HeapBase = .; - - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy (COPY): - { - *(.stack*) - } > RAM - - _ram_start = ORIGIN(RAM); - - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(RAM) + LENGTH(RAM); - __StackLimit = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - /* Top of head is the bottom of the stack */ - __HeapLimit = __StackLimit; - end = __HeapLimit; - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") - - /* Check that intvect is at the beginning of RAM */ - ASSERT(__intvect_start__ == ORIGIN(RAM), "intvect is not at beginning of RAM") -} diff --git a/hw/bsp/da14695_dk_usb/gcc_startup_da1469x.S b/hw/bsp/da14695_dk_usb/gcc_startup_da1469x.S deleted file mode 100644 index d47fbcd97..000000000 --- a/hw/bsp/da14695_dk_usb/gcc_startup_da1469x.S +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - #include "syscfg/syscfg.h" - - .syntax unified - .arch armv7-m - - .section .stack - .align 3 -#ifdef __STACK_SIZE - .equ Stack_Size, __STACK_SIZE -#else - .equ Stack_Size, 0xC00 -#endif - .equ SYS_CTRL_REG, 0x50000024 - .equ CACHE_FLASH_REG, 0x100C0040 - .equ RESET_STAT_REG, 0x500000BC - - .globl __StackTop - .globl __StackLimit -__StackLimit: - .space Stack_Size - .size __StackLimit, . - __StackLimit -__StackTop: - .size __StackTop, . - __StackTop - - .section .heap - .align 3 -#ifdef __HEAP_SIZE - .equ Heap_Size, __HEAP_SIZE -#else - .equ Heap_Size, 0 -#endif - .globl __HeapBase - .globl __HeapLimit -__HeapBase: - .if Heap_Size - .space Heap_Size - .endif - .size __HeapBase, . - __HeapBase -__HeapLimit: - .size __HeapLimit, . - __HeapLimit - - .section .isr_vector - .align 2 - .globl __isr_vector -__isr_vector: - .long __StackTop - .long Reset_Handler - /* Cortex-M33 interrupts */ - .long NMI_Handler - .long HardFault_Handler - .long MemoryManagement_Handler - .long BusFault_Handler - .long UsageFault_Handler - .long SecureFault_Handler - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long SVC_Handler - .long DebugMonitor_Handler - .long 0 /* Reserved */ - .long PendSV_Handler - .long SysTick_Handler - /* DA1469x interrupts */ - .long SENSOR_NODE_IRQHandler - .long DMA_IRQHandler - .long CHARGER_STATE_IRQHandler - .long CHARGER_ERROR_IRQHandler - .long CMAC2SYS_IRQHandler - .long UART_IRQHandler - .long UART2_IRQHandler - .long UART3_IRQHandler - .long I2C_IRQHandler - .long I2C2_IRQHandler - .long SPI_IRQHandler - .long SPI2_IRQHandler - .long PCM_IRQHandler - .long SRC_IN_IRQHandler - .long SRC_OUT_IRQHandler - .long USB_IRQHandler - .long TIMER_IRQHandler - .long TIMER2_IRQHandler - .long RTC_IRQHandler - .long KEY_WKUP_GPIO_IRQHandler - .long PDC_IRQHandler - .long VBUS_IRQHandler - .long MRM_IRQHandler - .long MOTOR_CONTROLLER_IRQHandler - .long TRNG_IRQHandler - .long DCDC_IRQHandler - .long XTAL32M_RDY_IRQHandler - .long ADC_IRQHandler - .long ADC2_IRQHandler - .long CRYPTO_IRQHandler - .long CAPTIMER1_IRQHandler - .long RFDIAG_IRQHandler - .long LCD_CONTROLLER_IRQHandler - .long PLL_LOCK_IRQHandler - .long TIMER3_IRQHandler - .long TIMER4_IRQHandler - .long LRA_IRQHandler - .long RTC_EVENT_IRQHandler - .long GPIO_P0_IRQHandler - .long GPIO_P1_IRQHandler - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .size __isr_vector, . - __isr_vector - - .text - .thumb - .thumb_func - .align 2 - .globl Reset_Handler - .type Reset_Handler, %function -Reset_Handler: - /* Make sure interrupt vector is remapped at 0x0 */ - ldr r1, =SYS_CTRL_REG - ldrh r2, [r1, #0] - orrs r2, r2, #8 - strh r2, [r1, #0] - -#if !MYNEWT_VAL(RAM_RESIDENT) -/* - * Flash is remapped at 0x0 with an offset, i.e. 0x0 does not correspond to - * 0x16000000 but to start of an image on flash. This is calculated from product - * header by 1st state bootloader and configured in CACHE_FLASH_REG. We need to - * retrieve proper offset value for calculations later. - */ - ldr r1, =CACHE_FLASH_REG - ldr r4, [r1, #0] - mov r2, r4 - mov r3, #0xFFFF - bic r4, r4, r3 /* CACHE_FLASH_REG[FLASH_REGION_BASE] */ - mov r3, #0xFFF0 - and r2, r2, r3 /* CACHE_FLASH_REG[FLASH_REGION_OFFSET] */ - lsr r2, r2, #2 - orr r4, r4, r2 - -/* Copy ISR vector from flash to RAM */ - ldr r1, =__isr_vector_start /* src ptr */ - ldr r2, =__isr_vector_end /* src end */ - ldr r3, =__intvect_start__ /* dst ptr */ -/* Make sure we copy from QSPIC address range, not from remapped range */ - cmp r1, r4 - itt lt - addlt r1, r1, r4 - addlt r2, r2, r4 -.loop_isr_copy: - cmp r1, r2 - ittt lt - ldrlt r0, [r1], #4 - strlt r0, [r3], #4 - blt .loop_isr_copy - -/* Copy QSPI code from flash to RAM */ - ldr r1, =__text_ram_addr /* src ptr */ - ldr r2, =__text_ram_start__ /* ptr */ - ldr r3, =__text_ram_end__ /* dst end */ -.loop_code_text_ram_copy: - cmp r2, r3 - ittt lt - ldrlt r0, [r1], #4 - strlt r0, [r2], #4 - blt .loop_code_text_ram_copy - -/* Copy data from flash to RAM */ - ldr r1, =__etext /* src ptr */ - ldr r2, =__data_start__ /* dst ptr */ - ldr r3, =__data_end__ /* dst end */ -.loop_data_copy: - cmp r2, r3 - ittt lt - ldrlt r0, [r1], #4 - strlt r0, [r2], #4 - blt .loop_data_copy -#endif - -/* Clear BSS */ - movs r0, 0 - ldr r1, =__bss_start__ - ldr r2, =__bss_end__ -.loop_bss_clear: - cmp r1, r2 - itt lt - strlt r0, [r1], #4 - blt .loop_bss_clear - - ldr r0, =__HeapBase - ldr r1, =__HeapLimit -/* Call static constructors */ - bl __libc_init_array - - bl SystemInit - bl main - - .pool - .size Reset_Handler, . - Reset_Handler - -/* Default interrupt handler */ - .type Default_Handler, %function -Default_Handler: - ldr r1, =SYS_CTRL_REG - ldrh r2, [r1, #0] - orrs r2, r2, #0x80 /* DEBUGGER_ENABLE */ - strh r2, [r1, #0] - b . - - .size Default_Handler, . - Default_Handler - -/* Default handlers for all interrupts */ - .macro IRQ handler - .weak \handler - .set \handler, Default_Handler - .endm - - /* Cortex-M33 interrupts */ - IRQ NMI_Handler - IRQ HardFault_Handler - IRQ MemoryManagement_Handler - IRQ BusFault_Handler - IRQ UsageFault_Handler - IRQ SecureFault_Handler - IRQ SVC_Handler - IRQ DebugMonitor_Handler - IRQ PendSV_Handler - IRQ SysTick_Handler - /* DA1469x interrupts */ - IRQ SENSOR_NODE_IRQHandler - IRQ DMA_IRQHandler - IRQ CHARGER_STATE_IRQHandler - IRQ CHARGER_ERROR_IRQHandler - IRQ CMAC2SYS_IRQHandler - IRQ UART_IRQHandler - IRQ UART2_IRQHandler - IRQ UART3_IRQHandler - IRQ I2C_IRQHandler - IRQ I2C2_IRQHandler - IRQ SPI_IRQHandler - IRQ SPI2_IRQHandler - IRQ PCM_IRQHandler - IRQ SRC_IN_IRQHandler - IRQ SRC_OUT_IRQHandler - IRQ USB_IRQHandler - IRQ TIMER_IRQHandler - IRQ TIMER2_IRQHandler - IRQ RTC_IRQHandler - IRQ KEY_WKUP_GPIO_IRQHandler - IRQ PDC_IRQHandler - IRQ VBUS_IRQHandler - IRQ MRM_IRQHandler - IRQ MOTOR_CONTROLLER_IRQHandler - IRQ TRNG_IRQHandler - IRQ DCDC_IRQHandler - IRQ XTAL32M_RDY_IRQHandler - IRQ ADC_IRQHandler - IRQ ADC2_IRQHandler - IRQ CRYPTO_IRQHandler - IRQ CAPTIMER1_IRQHandler - IRQ RFDIAG_IRQHandler - IRQ LCD_CONTROLLER_IRQHandler - IRQ PLL_LOCK_IRQHandler - IRQ TIMER3_IRQHandler - IRQ TIMER4_IRQHandler - IRQ LRA_IRQHandler - IRQ RTC_EVENT_IRQHandler - IRQ GPIO_P0_IRQHandler - IRQ GPIO_P1_IRQHandler - IRQ RESERVED40_IRQHandler - IRQ RESERVED41_IRQHandler - IRQ RESERVED42_IRQHandler - IRQ RESERVED43_IRQHandler - IRQ RESERVED44_IRQHandler - IRQ RESERVED45_IRQHandler - IRQ RESERVED46_IRQHandler - IRQ RESERVED47_IRQHandler - -.end diff --git a/hw/bsp/da14695_dk_usb/product_header.dump b/hw/bsp/da14695_dk_usb/product_header.dump deleted file mode 100644 index ea4842242..000000000 Binary files a/hw/bsp/da14695_dk_usb/product_header.dump and /dev/null differ diff --git a/hw/bsp/da14695_dk_usb/syscfg/syscfg.h b/hw/bsp/da14695_dk_usb/syscfg/syscfg.h deleted file mode 100644 index 6cbb4319e..000000000 --- a/hw/bsp/da14695_dk_usb/syscfg/syscfg.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * This file was generated by Apache newt version: 1.9.0-dev - */ - -#ifndef H_MYNEWT_SYSCFG_ -#define H_MYNEWT_SYSCFG_ - -/** - * This macro exists to ensure code includes this header when needed. If code - * checks the existence of a setting directly via ifdef without including this - * header, the setting macro will silently evaluate to 0. In contrast, an - * attempt to use these macros without including this header will result in a - * compiler error. - */ -#define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name -#define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val - -#ifndef MYNEWT_VAL_RAM_RESIDENT -#define MYNEWT_VAL_RAM_RESIDENT (0) -#endif - -#ifndef MYNEWT_VAL_MCU_GPIO_MAX_IRQ -#define MYNEWT_VAL_MCU_GPIO_MAX_IRQ (4) -#endif - -#ifndef MYNEWT_VAL_MCU_GPIO_RETAINABLE_NUM -#define MYNEWT_VAL_MCU_GPIO_RETAINABLE_NUM (-1) -#endif - -#ifndef MYNEWT_VAL_MCU_CLOCK_XTAL32M_SETTLE_TIME_US -#define MYNEWT_VAL_MCU_CLOCK_XTAL32M_SETTLE_TIME_US (2000) -#endif - -#endif diff --git a/hw/bsp/da1469x/boards/da14695_dk_usb/board.cmake b/hw/bsp/da1469x/boards/da14695_dk_usb/board.cmake new file mode 100644 index 000000000..f9ef2dc86 --- /dev/null +++ b/hw/bsp/da1469x/boards/da14695_dk_usb/board.cmake @@ -0,0 +1,4 @@ +set(JLINK_DEVICE DA14695) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/da1469x/boards/da14695_dk_usb/board.h b/hw/bsp/da1469x/boards/da14695_dk_usb/board.h new file mode 100644 index 000000000..5efdd43e0 --- /dev/null +++ b/hw/bsp/da1469x/boards/da14695_dk_usb/board.h @@ -0,0 +1,10 @@ +#ifndef BOARD_H +#define BOARD_H + +#define LED_PIN 33 // P1.1 +#define LED_STATE_ON 1 + +#define BUTTON_PIN 6 +#define BUTTON_STATE_ACTIVE 1 + +#endif diff --git a/hw/bsp/da1469x/boards/da14695_dk_usb/board.mk b/hw/bsp/da1469x/boards/da14695_dk_usb/board.mk new file mode 100644 index 000000000..1ca17ea00 --- /dev/null +++ b/hw/bsp/da1469x/boards/da14695_dk_usb/board.mk @@ -0,0 +1 @@ +JLINK_DEVICE = DA14695 diff --git a/hw/bsp/da1469x/boards/da14695_dk_usb/syscfg/syscfg.h b/hw/bsp/da1469x/boards/da14695_dk_usb/syscfg/syscfg.h new file mode 100644 index 000000000..6cbb4319e --- /dev/null +++ b/hw/bsp/da1469x/boards/da14695_dk_usb/syscfg/syscfg.h @@ -0,0 +1,34 @@ +/** + * This file was generated by Apache newt version: 1.9.0-dev + */ + +#ifndef H_MYNEWT_SYSCFG_ +#define H_MYNEWT_SYSCFG_ + +/** + * This macro exists to ensure code includes this header when needed. If code + * checks the existence of a setting directly via ifdef without including this + * header, the setting macro will silently evaluate to 0. In contrast, an + * attempt to use these macros without including this header will result in a + * compiler error. + */ +#define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name +#define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val + +#ifndef MYNEWT_VAL_RAM_RESIDENT +#define MYNEWT_VAL_RAM_RESIDENT (0) +#endif + +#ifndef MYNEWT_VAL_MCU_GPIO_MAX_IRQ +#define MYNEWT_VAL_MCU_GPIO_MAX_IRQ (4) +#endif + +#ifndef MYNEWT_VAL_MCU_GPIO_RETAINABLE_NUM +#define MYNEWT_VAL_MCU_GPIO_RETAINABLE_NUM (-1) +#endif + +#ifndef MYNEWT_VAL_MCU_CLOCK_XTAL32M_SETTLE_TIME_US +#define MYNEWT_VAL_MCU_CLOCK_XTAL32M_SETTLE_TIME_US (2000) +#endif + +#endif diff --git a/hw/bsp/da1469x/boards/da1469x_dk_pro/board.cmake b/hw/bsp/da1469x/boards/da1469x_dk_pro/board.cmake new file mode 100644 index 000000000..f6408b72b --- /dev/null +++ b/hw/bsp/da1469x/boards/da1469x_dk_pro/board.cmake @@ -0,0 +1,4 @@ +set(JLINK_DEVICE DA14699) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/da1469x/boards/da1469x_dk_pro/board.h b/hw/bsp/da1469x/boards/da1469x_dk_pro/board.h new file mode 100644 index 000000000..f969acf90 --- /dev/null +++ b/hw/bsp/da1469x/boards/da1469x_dk_pro/board.h @@ -0,0 +1,12 @@ +#ifndef BOARD_H +#define BOARD_H + +#define LED_PIN 33 +#define LED_STATE_ON 1 + +#define BUTTON_PIN 6 +#define BUTTON_STATE_ACTIVE 0 + +#define NEED_VBUS_MONITOR + +#endif diff --git a/hw/bsp/da1469x/boards/da1469x_dk_pro/board.mk b/hw/bsp/da1469x/boards/da1469x_dk_pro/board.mk new file mode 100644 index 000000000..40fe93b41 --- /dev/null +++ b/hw/bsp/da1469x/boards/da1469x_dk_pro/board.mk @@ -0,0 +1,2 @@ +# For flash-jlink target +JLINK_DEVICE = DA14699 diff --git a/hw/bsp/da1469x/boards/da1469x_dk_pro/syscfg/syscfg.h b/hw/bsp/da1469x/boards/da1469x_dk_pro/syscfg/syscfg.h new file mode 100644 index 000000000..6cbb4319e --- /dev/null +++ b/hw/bsp/da1469x/boards/da1469x_dk_pro/syscfg/syscfg.h @@ -0,0 +1,34 @@ +/** + * This file was generated by Apache newt version: 1.9.0-dev + */ + +#ifndef H_MYNEWT_SYSCFG_ +#define H_MYNEWT_SYSCFG_ + +/** + * This macro exists to ensure code includes this header when needed. If code + * checks the existence of a setting directly via ifdef without including this + * header, the setting macro will silently evaluate to 0. In contrast, an + * attempt to use these macros without including this header will result in a + * compiler error. + */ +#define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name +#define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val + +#ifndef MYNEWT_VAL_RAM_RESIDENT +#define MYNEWT_VAL_RAM_RESIDENT (0) +#endif + +#ifndef MYNEWT_VAL_MCU_GPIO_MAX_IRQ +#define MYNEWT_VAL_MCU_GPIO_MAX_IRQ (4) +#endif + +#ifndef MYNEWT_VAL_MCU_GPIO_RETAINABLE_NUM +#define MYNEWT_VAL_MCU_GPIO_RETAINABLE_NUM (-1) +#endif + +#ifndef MYNEWT_VAL_MCU_CLOCK_XTAL32M_SETTLE_TIME_US +#define MYNEWT_VAL_MCU_CLOCK_XTAL32M_SETTLE_TIME_US (2000) +#endif + +#endif diff --git a/hw/bsp/da1469x/family.c b/hw/bsp/da1469x/family.c new file mode 100644 index 000000000..70bedf6d9 --- /dev/null +++ b/hw/bsp/da1469x/family.c @@ -0,0 +1,142 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Jerzy Kasenberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "bsp/board_api.h" +#include "board.h" +#include +#include + +#define LED_STATE_OFF (1-LED_STATE_ON) + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_IRQHandler(void) { + tud_int_handler(0); +} + +// DA146xx driver function that must be called whenever VBUS changes. +extern void tusb_vbus_changed(bool present); + +#if defined(NEED_VBUS_MONITOR) && CFG_TUD_ENABLED +// VBUS change interrupt handler +void VBUS_IRQHandler(void) { + bool present = (CRG_TOP->ANA_STATUS_REG & CRG_TOP_ANA_STATUS_REG_VBUS_AVAILABLE_Msk) != 0; + // Clear VBUS interrupt + CRG_TOP->VBUS_IRQ_CLEAR_REG = 1; + + tusb_vbus_changed(present); +} +#endif + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ +void UnhandledIRQ(void) { + CRG_TOP->SYS_CTRL_REG = 0x80; + __BKPT(1); + while (1); +} + +void board_init(void) { + // LED + hal_gpio_init_out(LED_PIN, LED_STATE_ON); + + hal_gpio_init_out(1, 0); + hal_gpio_init_out(2, 0); + hal_gpio_init_out(3, 0); + hal_gpio_init_out(4, 0); + hal_gpio_init_out(5, 0); + + // Button + hal_gpio_init_in(BUTTON_PIN, BUTTON_STATE_ACTIVE ? HAL_GPIO_PULL_DOWN : HAL_GPIO_PULL_UP); + + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); + +#if CFG_TUD_ENABLED + #ifdef NEED_VBUS_MONITOR + // Setup interrupt for both connect and disconnect + CRG_TOP->VBUS_IRQ_MASK_REG = CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_FALL_Msk | + CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_RISE_Msk; + NVIC_SetPriority(VBUS_IRQn, 2); + // Trigger interrupt at the start to inform driver about VBUS state at start + // otherwise it could go unnoticed. + NVIC_SetPendingIRQ(VBUS_IRQn); + NVIC_EnableIRQ(VBUS_IRQn); + #else + // This board is USB powered there is no need to monitor VBUS line. Notify driver that VBUS is present. + tusb_vbus_changed(true); + #endif + + /* Setup USB IRQ */ + NVIC_SetPriority(USB_IRQn, 2); + NVIC_EnableIRQ(USB_IRQn); + + /* Use PLL96 / 2 clock not HCLK */ + CRG_TOP->CLK_CTRL_REG &= ~CRG_TOP_CLK_CTRL_REG_USB_CLK_SRC_Msk; + + mcu_gpio_set_pin_function(14, MCU_GPIO_MODE_INPUT, MCU_GPIO_FUNC_USB); + mcu_gpio_set_pin_function(15, MCU_GPIO_MODE_INPUT, MCU_GPIO_FUNC_USB); +#endif +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { + hal_gpio_write(LED_PIN, state ? LED_STATE_ON : LED_STATE_OFF); +} + +uint32_t board_button_read(void) { + return BUTTON_STATE_ACTIVE == hal_gpio_read(BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const* buf, int len) { + (void) buf; + (void) len; + + return 0; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; +} + +uint32_t board_millis(void) { + return system_ticks; +} +#endif diff --git a/hw/bsp/da1469x/family.cmake b/hw/bsp/da1469x/family.cmake new file mode 100644 index 000000000..8c89141fe --- /dev/null +++ b/hw/bsp/da1469x/family.cmake @@ -0,0 +1,141 @@ +include_guard() + +set(MCU_DIR ${TOP}/hw/mcu/dialog/da1469x) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +set(CMAKE_SYSTEM_PROCESSOR cortex-m33-nodsp CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(FAMILY_MCUS DA1469X CACHE INTERNAL "") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/da1469x.ld) + endif () + + if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) + set(STARTUP_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/gcc_startup_da1469x.S) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + endif () + + add_library(${BOARD_TARGET} STATIC + ${MCU_DIR}/src/system_da1469x.c + ${MCU_DIR}/src/da1469x_clock.c + ${MCU_DIR}/src/hal_gpio.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_compile_options(${BOARD_TARGET} PUBLIC -mthumb-interwork) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CORE_M33 + CFG_TUD_ENDPOINT0_SIZE=8 + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ${MCU_DIR}/include + ${MCU_DIR}/SDK_10.0.8.105/sdk/bsp/include + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -L${NRFX_DIR}/mdk + --specs=nosys.specs --specs=nano.specs + -nostartfiles + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -L${NRFX_DIR}/mdk + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ + +function(family_flash_jlink_dialog TARGET) + set(JLINKEXE JLinkExe) + set(JLINK_IF swd) + + # mkimage from sdk + set(MKIMAGE $ENV{HOME}/code/tinyusb-mcu-driver/dialog/SDK_10.0.8.105/binaries/mkimage) + + file(GENERATE OUTPUT $/version.h + CONTENT "#define SW_VERSION \"v_1.0.0.1\" +#define SW_VERSION_DATE \"2024-07-17 17:55\"" + ) + + file(GENERATE OUTPUT $/${TARGET}.jlink + CONTENT "r +halt +loadfile $/${TARGET}-image.bin 0x16000000 +r +go +exit" + ) + + add_custom_target(${TARGET}-image + DEPENDS ${TARGET} + COMMAND ${MKIMAGE} da1469x $/${TARGET}.bin $/version.h $/${TARGET}.bin.img + COMMAND cp ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/product_header.dump $/${TARGET}-image.bin + COMMAND cat $/${TARGET}.bin.img >> $/${TARGET}-image.bin + ) + add_custom_target(${TARGET}-jlink + DEPENDS ${TARGET}-image + COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile $/${TARGET}.jlink + ) +endfunction() + + +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_DA1469X ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/dialog/da146xx/dcd_da146xx.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_jlink_dialog(${TARGET}) +endfunction() diff --git a/hw/bsp/da1469x/family.mk b/hw/bsp/da1469x/family.mk new file mode 100644 index 000000000..f35fe2cb5 --- /dev/null +++ b/hw/bsp/da1469x/family.mk @@ -0,0 +1,62 @@ +MCU_DIR = hw/mcu/dialog/da1469x + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -flto \ + -mthumb \ + -mthumb-interwork \ + -mabi=aapcs \ + -mcpu=cortex-m33+nodsp \ + -mfloat-abi=hard \ + -mfpu=fpv5-sp-d16 \ + -DCORE_M33 \ + -DCFG_TUSB_MCU=OPT_MCU_DA1469X \ + -DCFG_TUD_ENDPOINT0_SIZE=8\ + +LDFLAGS_GCC += \ + -nostdlib \ + --specs=nosys.specs --specs=nano.specs + +# All source paths should be relative to the top level. +LD_FILE = $(FAMILY_PATH)/linker/da1469x.ld + +# While this is for da1469x chip, there is chance that da1468x chip family will also work +SRC_C += \ + src/portable/dialog/da146xx/dcd_da146xx.c \ + ${MCU_DIR}/src/system_da1469x.c \ + ${MCU_DIR}/src/da1469x_clock.c \ + ${MCU_DIR}/src/hal_gpio.c \ + +SRC_S += $(FAMILY_PATH)/gcc_startup_da1469x.S + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/${MCU_DIR}/include \ + $(TOP)/${MCU_DIR}/SDK_10.0.8.105/sdk/bsp/include + +# For freeRTOS port source +FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM33_NTZ/non_secure + +# flash using jlink but with some twists +flash: flash-dialog + +# SDK_BINARY_PATH is the path to the SDK binary files +SDK_BINARY_PATH = $(HOME)/code/tinyusb-mcu-driver/dialog/SDK_10.0.8.105/binaries +MKIMAGE = $(SDK_BINARY_PATH)/mkimage + +$(BUILD)/$(PROJECT)-image.bin: $(BUILD)/$(PROJECT).bin + @echo '#define SW_VERSION "v_1.0.0.1"' >$(BUILD)/version.h + @echo '#define SW_VERSION_DATE "'`date +"%Y-%m-%d %H:%M"`'"' >> $(BUILD)/version.h + $(MKIMAGE) da1469x $^ $(BUILD)/version.h $^.img + cp $(TOP)/$(FAMILY_PATH)/product_header.dump $(BUILD)/$(PROJECT)-image.bin + cat $^.img >> $(BUILD)/$(PROJECT)-image.bin + +flash-dialog: $(BUILD)/$(PROJECT)-image.bin + @echo r > $(BUILD)/$(BOARD).jlink + @echo halt >> $(BUILD)/$(BOARD).jlink + @echo loadfile $^ 0x16000000 >> $(BUILD)/$(BOARD).jlink + @echo r >> $(BUILD)/$(BOARD).jlink + @echo go >> $(BUILD)/$(BOARD).jlink + @echo exit >> $(BUILD)/$(BOARD).jlink + $(JLINKEXE) -device $(JLINK_DEVICE) -if $(JLINK_IF) -JTAGConf -1,-1 -speed auto -CommandFile $(BUILD)/$(BOARD).jlink diff --git a/hw/bsp/da1469x/gcc_startup_da1469x.S b/hw/bsp/da1469x/gcc_startup_da1469x.S new file mode 100644 index 000000000..d47fbcd97 --- /dev/null +++ b/hw/bsp/da1469x/gcc_startup_da1469x.S @@ -0,0 +1,301 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + #include "syscfg/syscfg.h" + + .syntax unified + .arch armv7-m + + .section .stack + .align 3 +#ifdef __STACK_SIZE + .equ Stack_Size, __STACK_SIZE +#else + .equ Stack_Size, 0xC00 +#endif + .equ SYS_CTRL_REG, 0x50000024 + .equ CACHE_FLASH_REG, 0x100C0040 + .equ RESET_STAT_REG, 0x500000BC + + .globl __StackTop + .globl __StackLimit +__StackLimit: + .space Stack_Size + .size __StackLimit, . - __StackLimit +__StackTop: + .size __StackTop, . - __StackTop + + .section .heap + .align 3 +#ifdef __HEAP_SIZE + .equ Heap_Size, __HEAP_SIZE +#else + .equ Heap_Size, 0 +#endif + .globl __HeapBase + .globl __HeapLimit +__HeapBase: + .if Heap_Size + .space Heap_Size + .endif + .size __HeapBase, . - __HeapBase +__HeapLimit: + .size __HeapLimit, . - __HeapLimit + + .section .isr_vector + .align 2 + .globl __isr_vector +__isr_vector: + .long __StackTop + .long Reset_Handler + /* Cortex-M33 interrupts */ + .long NMI_Handler + .long HardFault_Handler + .long MemoryManagement_Handler + .long BusFault_Handler + .long UsageFault_Handler + .long SecureFault_Handler + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long SVC_Handler + .long DebugMonitor_Handler + .long 0 /* Reserved */ + .long PendSV_Handler + .long SysTick_Handler + /* DA1469x interrupts */ + .long SENSOR_NODE_IRQHandler + .long DMA_IRQHandler + .long CHARGER_STATE_IRQHandler + .long CHARGER_ERROR_IRQHandler + .long CMAC2SYS_IRQHandler + .long UART_IRQHandler + .long UART2_IRQHandler + .long UART3_IRQHandler + .long I2C_IRQHandler + .long I2C2_IRQHandler + .long SPI_IRQHandler + .long SPI2_IRQHandler + .long PCM_IRQHandler + .long SRC_IN_IRQHandler + .long SRC_OUT_IRQHandler + .long USB_IRQHandler + .long TIMER_IRQHandler + .long TIMER2_IRQHandler + .long RTC_IRQHandler + .long KEY_WKUP_GPIO_IRQHandler + .long PDC_IRQHandler + .long VBUS_IRQHandler + .long MRM_IRQHandler + .long MOTOR_CONTROLLER_IRQHandler + .long TRNG_IRQHandler + .long DCDC_IRQHandler + .long XTAL32M_RDY_IRQHandler + .long ADC_IRQHandler + .long ADC2_IRQHandler + .long CRYPTO_IRQHandler + .long CAPTIMER1_IRQHandler + .long RFDIAG_IRQHandler + .long LCD_CONTROLLER_IRQHandler + .long PLL_LOCK_IRQHandler + .long TIMER3_IRQHandler + .long TIMER4_IRQHandler + .long LRA_IRQHandler + .long RTC_EVENT_IRQHandler + .long GPIO_P0_IRQHandler + .long GPIO_P1_IRQHandler + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .size __isr_vector, . - __isr_vector + + .text + .thumb + .thumb_func + .align 2 + .globl Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + /* Make sure interrupt vector is remapped at 0x0 */ + ldr r1, =SYS_CTRL_REG + ldrh r2, [r1, #0] + orrs r2, r2, #8 + strh r2, [r1, #0] + +#if !MYNEWT_VAL(RAM_RESIDENT) +/* + * Flash is remapped at 0x0 with an offset, i.e. 0x0 does not correspond to + * 0x16000000 but to start of an image on flash. This is calculated from product + * header by 1st state bootloader and configured in CACHE_FLASH_REG. We need to + * retrieve proper offset value for calculations later. + */ + ldr r1, =CACHE_FLASH_REG + ldr r4, [r1, #0] + mov r2, r4 + mov r3, #0xFFFF + bic r4, r4, r3 /* CACHE_FLASH_REG[FLASH_REGION_BASE] */ + mov r3, #0xFFF0 + and r2, r2, r3 /* CACHE_FLASH_REG[FLASH_REGION_OFFSET] */ + lsr r2, r2, #2 + orr r4, r4, r2 + +/* Copy ISR vector from flash to RAM */ + ldr r1, =__isr_vector_start /* src ptr */ + ldr r2, =__isr_vector_end /* src end */ + ldr r3, =__intvect_start__ /* dst ptr */ +/* Make sure we copy from QSPIC address range, not from remapped range */ + cmp r1, r4 + itt lt + addlt r1, r1, r4 + addlt r2, r2, r4 +.loop_isr_copy: + cmp r1, r2 + ittt lt + ldrlt r0, [r1], #4 + strlt r0, [r3], #4 + blt .loop_isr_copy + +/* Copy QSPI code from flash to RAM */ + ldr r1, =__text_ram_addr /* src ptr */ + ldr r2, =__text_ram_start__ /* ptr */ + ldr r3, =__text_ram_end__ /* dst end */ +.loop_code_text_ram_copy: + cmp r2, r3 + ittt lt + ldrlt r0, [r1], #4 + strlt r0, [r2], #4 + blt .loop_code_text_ram_copy + +/* Copy data from flash to RAM */ + ldr r1, =__etext /* src ptr */ + ldr r2, =__data_start__ /* dst ptr */ + ldr r3, =__data_end__ /* dst end */ +.loop_data_copy: + cmp r2, r3 + ittt lt + ldrlt r0, [r1], #4 + strlt r0, [r2], #4 + blt .loop_data_copy +#endif + +/* Clear BSS */ + movs r0, 0 + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ +.loop_bss_clear: + cmp r1, r2 + itt lt + strlt r0, [r1], #4 + blt .loop_bss_clear + + ldr r0, =__HeapBase + ldr r1, =__HeapLimit +/* Call static constructors */ + bl __libc_init_array + + bl SystemInit + bl main + + .pool + .size Reset_Handler, . - Reset_Handler + +/* Default interrupt handler */ + .type Default_Handler, %function +Default_Handler: + ldr r1, =SYS_CTRL_REG + ldrh r2, [r1, #0] + orrs r2, r2, #0x80 /* DEBUGGER_ENABLE */ + strh r2, [r1, #0] + b . + + .size Default_Handler, . - Default_Handler + +/* Default handlers for all interrupts */ + .macro IRQ handler + .weak \handler + .set \handler, Default_Handler + .endm + + /* Cortex-M33 interrupts */ + IRQ NMI_Handler + IRQ HardFault_Handler + IRQ MemoryManagement_Handler + IRQ BusFault_Handler + IRQ UsageFault_Handler + IRQ SecureFault_Handler + IRQ SVC_Handler + IRQ DebugMonitor_Handler + IRQ PendSV_Handler + IRQ SysTick_Handler + /* DA1469x interrupts */ + IRQ SENSOR_NODE_IRQHandler + IRQ DMA_IRQHandler + IRQ CHARGER_STATE_IRQHandler + IRQ CHARGER_ERROR_IRQHandler + IRQ CMAC2SYS_IRQHandler + IRQ UART_IRQHandler + IRQ UART2_IRQHandler + IRQ UART3_IRQHandler + IRQ I2C_IRQHandler + IRQ I2C2_IRQHandler + IRQ SPI_IRQHandler + IRQ SPI2_IRQHandler + IRQ PCM_IRQHandler + IRQ SRC_IN_IRQHandler + IRQ SRC_OUT_IRQHandler + IRQ USB_IRQHandler + IRQ TIMER_IRQHandler + IRQ TIMER2_IRQHandler + IRQ RTC_IRQHandler + IRQ KEY_WKUP_GPIO_IRQHandler + IRQ PDC_IRQHandler + IRQ VBUS_IRQHandler + IRQ MRM_IRQHandler + IRQ MOTOR_CONTROLLER_IRQHandler + IRQ TRNG_IRQHandler + IRQ DCDC_IRQHandler + IRQ XTAL32M_RDY_IRQHandler + IRQ ADC_IRQHandler + IRQ ADC2_IRQHandler + IRQ CRYPTO_IRQHandler + IRQ CAPTIMER1_IRQHandler + IRQ RFDIAG_IRQHandler + IRQ LCD_CONTROLLER_IRQHandler + IRQ PLL_LOCK_IRQHandler + IRQ TIMER3_IRQHandler + IRQ TIMER4_IRQHandler + IRQ LRA_IRQHandler + IRQ RTC_EVENT_IRQHandler + IRQ GPIO_P0_IRQHandler + IRQ GPIO_P1_IRQHandler + IRQ RESERVED40_IRQHandler + IRQ RESERVED41_IRQHandler + IRQ RESERVED42_IRQHandler + IRQ RESERVED43_IRQHandler + IRQ RESERVED44_IRQHandler + IRQ RESERVED45_IRQHandler + IRQ RESERVED46_IRQHandler + IRQ RESERVED47_IRQHandler + +.end diff --git a/hw/bsp/da1469x/linker/da1469x.ld b/hw/bsp/da1469x/linker/da1469x.ld new file mode 100644 index 000000000..8cc1d9d99 --- /dev/null +++ b/hw/bsp/da1469x/linker/da1469x.ld @@ -0,0 +1,244 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +MEMORY +{ + /* + * Flash is remapped at 0x0 by 1st stage bootloader, but this is done with + * an offset derived from image header thus it is safer to use remapped + * address space at 0x0 instead of QSPI_M address space at 0x16000000. + * Bootloader partition is 32K, but 9K is currently reserved for product + * header (8K) and image header (1K). + * First 512 bytes of SYSRAM are remapped at 0x0 and used as ISR vector + * (there's no need to reallocate ISR vector) and thus cannot be used by + * application. + */ + + FLASH (r) : ORIGIN = (0x00000000), LENGTH = (1024 * 1024) + RAM (rw) : ORIGIN = (0x20000000), LENGTH = (512 * 1024) +} + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __bssnz_start__ + * __bssnz_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + __text = .; + + .text : + { + __isr_vector_start = .; + KEEP(*(.isr_vector)) + /* ISR vector shall have exactly 512 bytes */ + . = __isr_vector_start + 0x200; + __isr_vector_end = .; + + *(.text) + *(.text.*) + + *(.libcmac.rom) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + *(.eh_frame*) + . = ALIGN(4); + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } > FLASH + + __exidx_start = .; + .ARM : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + . = ALIGN(4); + } > FLASH + __exidx_end = .; + + .intvect : + { + . = ALIGN(4); + __intvect_start__ = .; + . = . + (__isr_vector_end - __isr_vector_start); + . = ALIGN(4); + } > RAM + + .sleep_state (NOLOAD) : + { + . = ALIGN(4); + *(sleep_state) + } > RAM + + /* This section will be zeroed by RTT package init */ + .rtt (NOLOAD): + { + . = ALIGN(4); + *(.rtt) + . = ALIGN(4); + } > RAM + + __text_ram_addr = LOADADDR(.text_ram); + + .text_ram : + { + . = ALIGN(4); + __text_ram_start__ = .; + *(.text_ram*) + . = ALIGN(4); + __text_ram_end__ = .; + } > RAM AT > FLASH + + __etext = LOADADDR(.data); + + .data : + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + *(.preinit_array) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + *(SORT(.init_array.*)) + *(.init_array) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.jcr) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > RAM AT > FLASH + + .bssnz : + { + . = ALIGN(4); + __bssnz_start__ = .; + *(.bss.core.nz*) + . = ALIGN(4); + __bssnz_end__ = .; + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .cmac (NOLOAD) : + { + . = ALIGN(0x400); + *(.libcmac.ram) + } > RAM + + /* Heap starts after BSS */ + . = ALIGN(8); + __HeapBase = .; + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + _ram_start = ORIGIN(RAM); + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Top of head is the bottom of the stack */ + __HeapLimit = __StackLimit; + end = __HeapLimit; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") + + /* Check that intvect is at the beginning of RAM */ + ASSERT(__intvect_start__ == ORIGIN(RAM), "intvect is not at beginning of RAM") +} diff --git a/hw/bsp/da1469x/product_header.dump b/hw/bsp/da1469x/product_header.dump new file mode 100644 index 000000000..ea4842242 Binary files /dev/null and b/hw/bsp/da1469x/product_header.dump differ diff --git a/hw/bsp/da1469x_dk_pro/board.mk b/hw/bsp/da1469x_dk_pro/board.mk deleted file mode 100644 index 5282f93a3..000000000 --- a/hw/bsp/da1469x_dk_pro/board.mk +++ /dev/null @@ -1,56 +0,0 @@ -MCU_FAMILY_DIR = hw/mcu/dialog/da1469x - -CFLAGS += \ - -flto \ - -mthumb \ - -mthumb-interwork \ - -mabi=aapcs \ - -mcpu=cortex-m33+nodsp \ - -mfloat-abi=hard \ - -mfpu=fpv5-sp-d16 \ - -nostdlib \ - -DCORE_M33 \ - -DCFG_TUSB_MCU=OPT_MCU_DA1469X \ - -DCFG_TUD_ENDPOINT0_SIZE=8\ - -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs - -# All source paths should be relative to the top level. -LD_FILE = hw/bsp/$(BOARD)/da1469x.ld - -# While this is for da1469x chip, there is chance that da1468x chip family will also work -SRC_C += \ - src/portable/dialog/da146xx/dcd_da146xx.c \ - $(MCU_FAMILY_DIR)/src/system_da1469x.c \ - $(MCU_FAMILY_DIR)/src/da1469x_clock.c \ - $(MCU_FAMILY_DIR)/src/hal_gpio.c \ - -SRC_S += hw/bsp/$(BOARD)/gcc_startup_da1469x.S - -INC += \ - $(TOP)/hw/bsp/$(BOARD) \ - $(TOP)/$(MCU_FAMILY_DIR)/include \ - $(TOP)/$(MCU_FAMILY_DIR)/SDK_10.0.8.105/sdk/bsp/include - -# For freeRTOS port source -FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM33_NTZ/non_secure - -# For flash-jlink target -JLINK_DEVICE = DA14699 - -# flash using jlink but with some twists -flash: flash-dialog - -flash-dialog: $(BUILD)/$(PROJECT).bin - @echo '#define SW_VERSION "v_1.0.0.1"' >$(BUILD)/version.h - @echo '#define SW_VERSION_DATE "'`date +"%Y-%m-%d %H:%M"`'"' >>$(BUILD)/version.h - mkimage da1469x $(BUILD)/$(PROJECT).bin $(BUILD)/version.h $^.img - cp $(TOP)/hw/bsp/$(BOARD)/product_header.dump $(BUILD)/$(BOARD)-image.bin - cat $^.img >> $(BUILD)/$(BOARD)-image.bin - @echo r > $(BUILD)/$(BOARD).jlink - @echo halt >> $(BUILD)/$(BOARD).jlink - @echo loadfile $(BUILD)/$(BOARD)-image.bin 0x16000000 >> $(BUILD)/$(BOARD).jlink - @echo r >> $(BUILD)/$(BOARD).jlink - @echo go >> $(BUILD)/$(BOARD).jlink - @echo exit >> $(BUILD)/$(BOARD).jlink - $(JLINKEXE) -device $(JLINK_DEVICE) -if $(JLINK_IF) -JTAGConf -1,-1 -speed auto -CommandFile $(BUILD)/$(BOARD).jlink diff --git a/hw/bsp/da1469x_dk_pro/da1469x-dk-pro.c b/hw/bsp/da1469x_dk_pro/da1469x-dk-pro.c deleted file mode 100644 index 21bd62714..000000000 --- a/hw/bsp/da1469x_dk_pro/da1469x-dk-pro.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Jerzy Kasenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "bsp/board_api.h" -#include -#include - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB_IRQHandler(void) -{ - tud_int_handler(0); -} - -#if CFG_TUD_ENABLED -// DA146xx driver function that must be called whenever VBUS changes -extern void tusb_vbus_changed(bool present); - -// VBUS change interrupt handler -void VBUS_IRQHandler(void) -{ - bool present = (CRG_TOP->ANA_STATUS_REG & CRG_TOP_ANA_STATUS_REG_VBUS_AVAILABLE_Msk) != 0; - // Clear VBUS interrupt - CRG_TOP->VBUS_IRQ_CLEAR_REG = 1; - - tusb_vbus_changed(present); -} -#endif - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM -//--------------------------------------------------------------------+ - -#define LED_PIN 33 -#define LED_STATE_ON 1 -#define LED_STATE_OFF 0 - -#define BUTTON_PIN 6 - -void UnhandledIRQ(void) -{ - CRG_TOP->SYS_CTRL_REG = 0x80; - __BKPT(1); - while(1); -} - -void board_init(void) -{ - // LED - hal_gpio_init_out(LED_PIN, LED_STATE_ON); - - hal_gpio_init_out(1, 0); - hal_gpio_init_out(2, 0); - hal_gpio_init_out(3, 0); - hal_gpio_init_out(4, 0); - hal_gpio_init_out(5, 0); - - // Button - hal_gpio_init_in(BUTTON_PIN, HAL_GPIO_PULL_UP); - - // 1ms tick timer - SysTick_Config(SystemCoreClock / 1000); - -#if CFG_TUD_ENABLED - // Setup interrupt for both connect and disconnect - CRG_TOP->VBUS_IRQ_MASK_REG = CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_FALL_Msk | - CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_RISE_Msk; - NVIC_SetPriority(VBUS_IRQn, 2); - // Trigger interrupt at the start to inform driver about VBUS state at start - // otherwise it could go unnoticed. - NVIC_SetPendingIRQ(VBUS_IRQn); - NVIC_EnableIRQ(VBUS_IRQn); - - /* Setup USB IRQ */ - NVIC_SetPriority(USB_IRQn, 2); - NVIC_EnableIRQ(USB_IRQn); - - /* Use PLL96 / 2 clock not HCLK */ - CRG_TOP->CLK_CTRL_REG &= ~CRG_TOP_CLK_CTRL_REG_USB_CLK_SRC_Msk; - - mcu_gpio_set_pin_function(14, MCU_GPIO_MODE_INPUT, MCU_GPIO_FUNC_USB); - mcu_gpio_set_pin_function(15, MCU_GPIO_MODE_INPUT, MCU_GPIO_FUNC_USB); -#endif -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) -{ - hal_gpio_write(LED_PIN, state ? LED_STATE_ON : LED_STATE_OFF); -} - -uint32_t board_button_read(void) -{ - // button is active LOW - return hal_gpio_read(BUTTON_PIN) ^ 1; -} - -int board_uart_read(uint8_t* buf, int len) -{ - (void)buf; - (void)len; - return 0; -} - -int board_uart_write(void const * buf, int len) -{ - (void)buf; - (void)len; - - return 0; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; -void SysTick_Handler(void) -{ - system_ticks++; -} - -uint32_t board_millis(void) -{ - return system_ticks; -} -#endif diff --git a/hw/bsp/da1469x_dk_pro/da1469x.ld b/hw/bsp/da1469x_dk_pro/da1469x.ld deleted file mode 100644 index 8cc1d9d99..000000000 --- a/hw/bsp/da1469x_dk_pro/da1469x.ld +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -MEMORY -{ - /* - * Flash is remapped at 0x0 by 1st stage bootloader, but this is done with - * an offset derived from image header thus it is safer to use remapped - * address space at 0x0 instead of QSPI_M address space at 0x16000000. - * Bootloader partition is 32K, but 9K is currently reserved for product - * header (8K) and image header (1K). - * First 512 bytes of SYSRAM are remapped at 0x0 and used as ISR vector - * (there's no need to reallocate ISR vector) and thus cannot be used by - * application. - */ - - FLASH (r) : ORIGIN = (0x00000000), LENGTH = (1024 * 1024) - RAM (rw) : ORIGIN = (0x20000000), LENGTH = (512 * 1024) -} - -OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") - -/* Linker script to place sections and symbol values. Should be used together - * with other linker script that defines memory regions FLASH and RAM. - * It references following symbols, which must be defined in code: - * Reset_Handler : Entry of reset handler - * - * It defines following symbols, which code can use without definition: - * __exidx_start - * __exidx_end - * __etext - * __data_start__ - * __preinit_array_start - * __preinit_array_end - * __init_array_start - * __init_array_end - * __fini_array_start - * __fini_array_end - * __data_end__ - * __bss_start__ - * __bss_end__ - * __HeapBase - * __HeapLimit - * __StackLimit - * __StackTop - * __stack - * __bssnz_start__ - * __bssnz_end__ - */ -ENTRY(Reset_Handler) - -SECTIONS -{ - __text = .; - - .text : - { - __isr_vector_start = .; - KEEP(*(.isr_vector)) - /* ISR vector shall have exactly 512 bytes */ - . = __isr_vector_start + 0x200; - __isr_vector_end = .; - - *(.text) - *(.text.*) - - *(.libcmac.rom) - - KEEP(*(.init)) - KEEP(*(.fini)) - - /* .ctors */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - - /* .dtors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - *(.rodata*) - - *(.eh_frame*) - . = ALIGN(4); - } > FLASH - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - . = ALIGN(4); - } > FLASH - - __exidx_start = .; - .ARM : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - . = ALIGN(4); - } > FLASH - __exidx_end = .; - - .intvect : - { - . = ALIGN(4); - __intvect_start__ = .; - . = . + (__isr_vector_end - __isr_vector_start); - . = ALIGN(4); - } > RAM - - .sleep_state (NOLOAD) : - { - . = ALIGN(4); - *(sleep_state) - } > RAM - - /* This section will be zeroed by RTT package init */ - .rtt (NOLOAD): - { - . = ALIGN(4); - *(.rtt) - . = ALIGN(4); - } > RAM - - __text_ram_addr = LOADADDR(.text_ram); - - .text_ram : - { - . = ALIGN(4); - __text_ram_start__ = .; - *(.text_ram*) - . = ALIGN(4); - __text_ram_end__ = .; - } > RAM AT > FLASH - - __etext = LOADADDR(.data); - - .data : - { - __data_start__ = .; - *(vtable) - *(.data*) - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - *(.preinit_array) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - *(SORT(.init_array.*)) - *(.init_array) - PROVIDE_HIDDEN (__init_array_end = .); - - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - *(SORT(.fini_array.*)) - *(.fini_array) - PROVIDE_HIDDEN (__fini_array_end = .); - - *(.jcr) - . = ALIGN(4); - /* All data end */ - __data_end__ = .; - } > RAM AT > FLASH - - .bssnz : - { - . = ALIGN(4); - __bssnz_start__ = .; - *(.bss.core.nz*) - . = ALIGN(4); - __bssnz_end__ = .; - } > RAM - - .bss : - { - . = ALIGN(4); - __bss_start__ = .; - *(.bss*) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .cmac (NOLOAD) : - { - . = ALIGN(0x400); - *(.libcmac.ram) - } > RAM - - /* Heap starts after BSS */ - . = ALIGN(8); - __HeapBase = .; - - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy (COPY): - { - *(.stack*) - } > RAM - - _ram_start = ORIGIN(RAM); - - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(RAM) + LENGTH(RAM); - __StackLimit = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - /* Top of head is the bottom of the stack */ - __HeapLimit = __StackLimit; - end = __HeapLimit; - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") - - /* Check that intvect is at the beginning of RAM */ - ASSERT(__intvect_start__ == ORIGIN(RAM), "intvect is not at beginning of RAM") -} diff --git a/hw/bsp/da1469x_dk_pro/gcc_startup_da1469x.S b/hw/bsp/da1469x_dk_pro/gcc_startup_da1469x.S deleted file mode 100644 index d47fbcd97..000000000 --- a/hw/bsp/da1469x_dk_pro/gcc_startup_da1469x.S +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - #include "syscfg/syscfg.h" - - .syntax unified - .arch armv7-m - - .section .stack - .align 3 -#ifdef __STACK_SIZE - .equ Stack_Size, __STACK_SIZE -#else - .equ Stack_Size, 0xC00 -#endif - .equ SYS_CTRL_REG, 0x50000024 - .equ CACHE_FLASH_REG, 0x100C0040 - .equ RESET_STAT_REG, 0x500000BC - - .globl __StackTop - .globl __StackLimit -__StackLimit: - .space Stack_Size - .size __StackLimit, . - __StackLimit -__StackTop: - .size __StackTop, . - __StackTop - - .section .heap - .align 3 -#ifdef __HEAP_SIZE - .equ Heap_Size, __HEAP_SIZE -#else - .equ Heap_Size, 0 -#endif - .globl __HeapBase - .globl __HeapLimit -__HeapBase: - .if Heap_Size - .space Heap_Size - .endif - .size __HeapBase, . - __HeapBase -__HeapLimit: - .size __HeapLimit, . - __HeapLimit - - .section .isr_vector - .align 2 - .globl __isr_vector -__isr_vector: - .long __StackTop - .long Reset_Handler - /* Cortex-M33 interrupts */ - .long NMI_Handler - .long HardFault_Handler - .long MemoryManagement_Handler - .long BusFault_Handler - .long UsageFault_Handler - .long SecureFault_Handler - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long SVC_Handler - .long DebugMonitor_Handler - .long 0 /* Reserved */ - .long PendSV_Handler - .long SysTick_Handler - /* DA1469x interrupts */ - .long SENSOR_NODE_IRQHandler - .long DMA_IRQHandler - .long CHARGER_STATE_IRQHandler - .long CHARGER_ERROR_IRQHandler - .long CMAC2SYS_IRQHandler - .long UART_IRQHandler - .long UART2_IRQHandler - .long UART3_IRQHandler - .long I2C_IRQHandler - .long I2C2_IRQHandler - .long SPI_IRQHandler - .long SPI2_IRQHandler - .long PCM_IRQHandler - .long SRC_IN_IRQHandler - .long SRC_OUT_IRQHandler - .long USB_IRQHandler - .long TIMER_IRQHandler - .long TIMER2_IRQHandler - .long RTC_IRQHandler - .long KEY_WKUP_GPIO_IRQHandler - .long PDC_IRQHandler - .long VBUS_IRQHandler - .long MRM_IRQHandler - .long MOTOR_CONTROLLER_IRQHandler - .long TRNG_IRQHandler - .long DCDC_IRQHandler - .long XTAL32M_RDY_IRQHandler - .long ADC_IRQHandler - .long ADC2_IRQHandler - .long CRYPTO_IRQHandler - .long CAPTIMER1_IRQHandler - .long RFDIAG_IRQHandler - .long LCD_CONTROLLER_IRQHandler - .long PLL_LOCK_IRQHandler - .long TIMER3_IRQHandler - .long TIMER4_IRQHandler - .long LRA_IRQHandler - .long RTC_EVENT_IRQHandler - .long GPIO_P0_IRQHandler - .long GPIO_P1_IRQHandler - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .size __isr_vector, . - __isr_vector - - .text - .thumb - .thumb_func - .align 2 - .globl Reset_Handler - .type Reset_Handler, %function -Reset_Handler: - /* Make sure interrupt vector is remapped at 0x0 */ - ldr r1, =SYS_CTRL_REG - ldrh r2, [r1, #0] - orrs r2, r2, #8 - strh r2, [r1, #0] - -#if !MYNEWT_VAL(RAM_RESIDENT) -/* - * Flash is remapped at 0x0 with an offset, i.e. 0x0 does not correspond to - * 0x16000000 but to start of an image on flash. This is calculated from product - * header by 1st state bootloader and configured in CACHE_FLASH_REG. We need to - * retrieve proper offset value for calculations later. - */ - ldr r1, =CACHE_FLASH_REG - ldr r4, [r1, #0] - mov r2, r4 - mov r3, #0xFFFF - bic r4, r4, r3 /* CACHE_FLASH_REG[FLASH_REGION_BASE] */ - mov r3, #0xFFF0 - and r2, r2, r3 /* CACHE_FLASH_REG[FLASH_REGION_OFFSET] */ - lsr r2, r2, #2 - orr r4, r4, r2 - -/* Copy ISR vector from flash to RAM */ - ldr r1, =__isr_vector_start /* src ptr */ - ldr r2, =__isr_vector_end /* src end */ - ldr r3, =__intvect_start__ /* dst ptr */ -/* Make sure we copy from QSPIC address range, not from remapped range */ - cmp r1, r4 - itt lt - addlt r1, r1, r4 - addlt r2, r2, r4 -.loop_isr_copy: - cmp r1, r2 - ittt lt - ldrlt r0, [r1], #4 - strlt r0, [r3], #4 - blt .loop_isr_copy - -/* Copy QSPI code from flash to RAM */ - ldr r1, =__text_ram_addr /* src ptr */ - ldr r2, =__text_ram_start__ /* ptr */ - ldr r3, =__text_ram_end__ /* dst end */ -.loop_code_text_ram_copy: - cmp r2, r3 - ittt lt - ldrlt r0, [r1], #4 - strlt r0, [r2], #4 - blt .loop_code_text_ram_copy - -/* Copy data from flash to RAM */ - ldr r1, =__etext /* src ptr */ - ldr r2, =__data_start__ /* dst ptr */ - ldr r3, =__data_end__ /* dst end */ -.loop_data_copy: - cmp r2, r3 - ittt lt - ldrlt r0, [r1], #4 - strlt r0, [r2], #4 - blt .loop_data_copy -#endif - -/* Clear BSS */ - movs r0, 0 - ldr r1, =__bss_start__ - ldr r2, =__bss_end__ -.loop_bss_clear: - cmp r1, r2 - itt lt - strlt r0, [r1], #4 - blt .loop_bss_clear - - ldr r0, =__HeapBase - ldr r1, =__HeapLimit -/* Call static constructors */ - bl __libc_init_array - - bl SystemInit - bl main - - .pool - .size Reset_Handler, . - Reset_Handler - -/* Default interrupt handler */ - .type Default_Handler, %function -Default_Handler: - ldr r1, =SYS_CTRL_REG - ldrh r2, [r1, #0] - orrs r2, r2, #0x80 /* DEBUGGER_ENABLE */ - strh r2, [r1, #0] - b . - - .size Default_Handler, . - Default_Handler - -/* Default handlers for all interrupts */ - .macro IRQ handler - .weak \handler - .set \handler, Default_Handler - .endm - - /* Cortex-M33 interrupts */ - IRQ NMI_Handler - IRQ HardFault_Handler - IRQ MemoryManagement_Handler - IRQ BusFault_Handler - IRQ UsageFault_Handler - IRQ SecureFault_Handler - IRQ SVC_Handler - IRQ DebugMonitor_Handler - IRQ PendSV_Handler - IRQ SysTick_Handler - /* DA1469x interrupts */ - IRQ SENSOR_NODE_IRQHandler - IRQ DMA_IRQHandler - IRQ CHARGER_STATE_IRQHandler - IRQ CHARGER_ERROR_IRQHandler - IRQ CMAC2SYS_IRQHandler - IRQ UART_IRQHandler - IRQ UART2_IRQHandler - IRQ UART3_IRQHandler - IRQ I2C_IRQHandler - IRQ I2C2_IRQHandler - IRQ SPI_IRQHandler - IRQ SPI2_IRQHandler - IRQ PCM_IRQHandler - IRQ SRC_IN_IRQHandler - IRQ SRC_OUT_IRQHandler - IRQ USB_IRQHandler - IRQ TIMER_IRQHandler - IRQ TIMER2_IRQHandler - IRQ RTC_IRQHandler - IRQ KEY_WKUP_GPIO_IRQHandler - IRQ PDC_IRQHandler - IRQ VBUS_IRQHandler - IRQ MRM_IRQHandler - IRQ MOTOR_CONTROLLER_IRQHandler - IRQ TRNG_IRQHandler - IRQ DCDC_IRQHandler - IRQ XTAL32M_RDY_IRQHandler - IRQ ADC_IRQHandler - IRQ ADC2_IRQHandler - IRQ CRYPTO_IRQHandler - IRQ CAPTIMER1_IRQHandler - IRQ RFDIAG_IRQHandler - IRQ LCD_CONTROLLER_IRQHandler - IRQ PLL_LOCK_IRQHandler - IRQ TIMER3_IRQHandler - IRQ TIMER4_IRQHandler - IRQ LRA_IRQHandler - IRQ RTC_EVENT_IRQHandler - IRQ GPIO_P0_IRQHandler - IRQ GPIO_P1_IRQHandler - IRQ RESERVED40_IRQHandler - IRQ RESERVED41_IRQHandler - IRQ RESERVED42_IRQHandler - IRQ RESERVED43_IRQHandler - IRQ RESERVED44_IRQHandler - IRQ RESERVED45_IRQHandler - IRQ RESERVED46_IRQHandler - IRQ RESERVED47_IRQHandler - -.end diff --git a/hw/bsp/da1469x_dk_pro/product_header.dump b/hw/bsp/da1469x_dk_pro/product_header.dump deleted file mode 100644 index ea4842242..000000000 Binary files a/hw/bsp/da1469x_dk_pro/product_header.dump and /dev/null differ diff --git a/hw/bsp/da1469x_dk_pro/syscfg/syscfg.h b/hw/bsp/da1469x_dk_pro/syscfg/syscfg.h deleted file mode 100644 index 6cbb4319e..000000000 --- a/hw/bsp/da1469x_dk_pro/syscfg/syscfg.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * This file was generated by Apache newt version: 1.9.0-dev - */ - -#ifndef H_MYNEWT_SYSCFG_ -#define H_MYNEWT_SYSCFG_ - -/** - * This macro exists to ensure code includes this header when needed. If code - * checks the existence of a setting directly via ifdef without including this - * header, the setting macro will silently evaluate to 0. In contrast, an - * attempt to use these macros without including this header will result in a - * compiler error. - */ -#define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name -#define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val - -#ifndef MYNEWT_VAL_RAM_RESIDENT -#define MYNEWT_VAL_RAM_RESIDENT (0) -#endif - -#ifndef MYNEWT_VAL_MCU_GPIO_MAX_IRQ -#define MYNEWT_VAL_MCU_GPIO_MAX_IRQ (4) -#endif - -#ifndef MYNEWT_VAL_MCU_GPIO_RETAINABLE_NUM -#define MYNEWT_VAL_MCU_GPIO_RETAINABLE_NUM (-1) -#endif - -#ifndef MYNEWT_VAL_MCU_CLOCK_XTAL32M_SETTLE_TIME_US -#define MYNEWT_VAL_MCU_CLOCK_XTAL32M_SETTLE_TIME_US (2000) -#endif - -#endif -- cgit v1.3.1 From 0004faca83f3fa3128fa69b6f97ac711f30d2d20 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Jul 2024 19:29:21 +0700 Subject: minor update hid device --- src/class/hid/hid_device.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 7168ab3d5..00f6fc474 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -46,16 +46,16 @@ typedef struct { uint8_t itf_protocol; // Boot mouse or keyboard uint16_t report_desc_len; - CFG_TUSB_MEM_ALIGN uint8_t protocol_mode; // Boot (0) or Report protocol (1) - CFG_TUSB_MEM_ALIGN uint8_t idle_rate; // up to application to handle idle rate - - CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE]; - CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE]; - CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf[CFG_TUD_HID_EP_BUFSIZE]; + uint8_t protocol_mode; // Boot (0) or Report protocol (1) + uint8_t idle_rate; // up to application to handle idle rate // TODO save hid descriptor since host can specifically request this after enumeration // Note: HID descriptor may be not available from application after enumeration tusb_hid_descriptor_hid_t const *hid_descriptor; + + uint8_t ctrl_buf[CFG_TUD_HID_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE]; } hidd_interface_t; CFG_TUD_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID]; -- cgit v1.3.1 From e1e68cdb9b968d03d39336a02ec0d9df40aea870 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Jul 2024 19:30:08 +0700 Subject: bump up ch32 v20x and v307 deps --- tools/get_deps.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/get_deps.py b/tools/get_deps.py index 92bfb86a2..555e2d707 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -172,10 +172,10 @@ deps_optional = { '7578cae0b21f86dd053a1f781b2fc6ab99d0ec17', 'ch32v10x'], 'hw/mcu/wch/ch32v20x': ['https://github.com/openwch/ch32v20x.git', - 'de6d68c654340d7f27b00cebbfc9aa2740a1abc2', + 'c4c38f507e258a4e69b059ccc2dc27dde33cea1b', 'ch32v20x'], 'hw/mcu/wch/ch32v307': ['https://github.com/openwch/ch32v307.git', - '17761f5cf9dbbf2dcf665b7c04934188add20082', + '184f21b852cb95eed58e86e901837bc9fff68775', 'ch32v307'], 'hw/mcu/wch/ch32f20x': ['https://github.com/openwch/ch32f20x.git', '77c4095087e5ed2c548ec9058e655d0b8757663b', -- cgit v1.3.1 From 0e53b0b8468ab4abadb4539caec0606399c6c1e3 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Jul 2024 19:45:40 +0700 Subject: update workflow build ci --- .github/workflows/ci_set_matrix.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 5584b8312..2a00e5413 100644 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -16,6 +16,7 @@ family_list = { "broadcom_32bit": ["arm-gcc"], "broadcom_64bit": ["aarch64-gcc"], "ch32v10x ch32v20x ch32v307 fomu gd32vf103": ["riscv-gcc"], + "da1469x": ["arm-gcc"], "imxrt": ["arm-gcc", "arm-clang"], "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"], "lpc11 lpc13 lpc15": ["arm-gcc", "arm-clang"], @@ -36,7 +37,7 @@ family_list = { "stm32f7": ["arm-gcc", "arm-clang", "arm-iar"], "stm32g0 stm32g4 stm32h5": ["arm-gcc", "arm-clang", "arm-iar"], "stm32h7": ["arm-gcc", "arm-clang", "arm-iar"], - "stm32l4 stm32u5 stm32wb": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32l0 stm32l4 stm32u5 stm32wb": ["arm-gcc", "arm-clang", "arm-iar"], "xmc4000": ["arm-gcc"], } -- cgit v1.3.1 From daa7acd585f5217d69afbfe0029c7fc15a956fad Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Jul 2024 20:40:27 +0700 Subject: add FreeRTOSConfig.h for da1469 --- hw/bsp/da1469x/FreeRTOSConfig/FreeRTOSConfig.h | 150 +++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 hw/bsp/da1469x/FreeRTOSConfig/FreeRTOSConfig.h diff --git a/hw/bsp/da1469x/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/da1469x/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..4d4379a6f --- /dev/null +++ b/hw/bsp/da1469x/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,150 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "DA1469xAB.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) +#define configRUN_FREERTOS_SECURE_ONLY 1 + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 4 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< Date: Wed, 17 Jul 2024 13:03:09 +0100 Subject: RP2040: Use our own unaligned memcpy to avoid alignment faults with some memcpy implementations --- src/portable/raspberrypi/rp2040/rp2040_usb.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 1ca711c77..c5d1ba3ce 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -53,6 +53,14 @@ TU_ATTR_ALWAYS_INLINE static inline bool is_host_mode(void) { //--------------------------------------------------------------------+ // Implementation //--------------------------------------------------------------------+ +// Provide own byte by byte memcpy as not all copies are aligned +static void unaligned_memcpy(void *dst, const void *src, size_t n) { + uint8_t *dst_byte = (uint8_t*)dst; + const uint8_t *src_byte = (const uint8_t*)src; + while (n--) { + *dst_byte++ = *src_byte++; + } +} void rp2040_usb_init(void) { // Reset usb controller @@ -125,7 +133,7 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint* ep, if (!ep->rx) { // Copy data from user buffer to hw buffer - memcpy(ep->hw_data_buf + buf_id * 64, ep->user_buf, buflen); + unaligned_memcpy(ep->hw_data_buf + buf_id * 64, ep->user_buf, buflen); ep->user_buf += buflen; // Mark as full @@ -230,7 +238,7 @@ static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint* ep, uin // we have received AFTER we have copied it to the user buffer at the appropriate offset assert(buf_ctrl & USB_BUF_CTRL_FULL); - memcpy(ep->user_buf, ep->hw_data_buf + buf_id * 64, xferred_bytes); + unaligned_memcpy(ep->user_buf, ep->hw_data_buf + buf_id * 64, xferred_bytes); ep->xferred_len = (uint16_t) (ep->xferred_len + xferred_bytes); ep->user_buf += xferred_bytes; } -- cgit v1.3.1 From 3804ab9a67737732fe6bcc8e0b016ea00d47ff12 Mon Sep 17 00:00:00 2001 From: Liam Fraser Date: Wed, 17 Jul 2024 15:40:34 +0100 Subject: RP2040: no need to clear usb_hw (usb registers) as they are reset to default state by a hardware reset --- src/portable/raspberrypi/rp2040/rp2040_usb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index c5d1ba3ce..43f48da39 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -75,7 +75,6 @@ void rp2040_usb_init(void) { #pragma GCC diagnostic ignored "-Wstringop-overflow" #endif #endif - memset(usb_hw, 0, sizeof(*usb_hw)); memset(usb_dpram, 0, sizeof(*usb_dpram)); #ifdef __GNUC__ #pragma GCC diagnostic pop -- cgit v1.3.1 From 15766ad9885d5f3308d98dce7088aacb6a99282d Mon Sep 17 00:00:00 2001 From: YixingShen Date: Thu, 18 Jul 2024 00:46:20 +0800 Subject: fixed _find_desc_format --- src/class/video/video_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 4218835aa..c544a09fe 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -398,7 +398,7 @@ static inline void const *_find_desc_format(void const *beg, void const *end, ui if ((fmt == VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED || fmt == VIDEO_CS_ITF_VS_FORMAT_MJPEG || fmt == VIDEO_CS_ITF_VS_FORMAT_DV || - fmt == VIDEO_CS_ITF_VS_FRAME_FRAME_BASED) && + fmt == VIDEO_CS_ITF_VS_FORMAT_FRAME_BASED) && fmtnum == p[3]) { return cur; } -- cgit v1.3.1 From ea5deb001868afd863ab88433f17520c951970ae Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 18 Jul 2024 09:24:29 +0700 Subject: add unique id for imxrt --- hw/bsp/board_api.h | 4 ++-- hw/bsp/imxrt/family.c | 24 ++++++++++++++++++++++++ hw/bsp/imxrt/family.cmake | 2 ++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/hw/bsp/board_api.h b/hw/bsp/board_api.h index 774deca24..a458a3fdc 100644 --- a/hw/bsp/board_api.h +++ b/hw/bsp/board_api.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _BOARD_API_H_ -#define _BOARD_API_H_ +#ifndef BOARD_API_H_ +#define BOARD_API_H_ #ifdef __cplusplus extern "C" { diff --git a/hw/bsp/imxrt/family.c b/hw/bsp/imxrt/family.c index c9c4918ef..2f305aa4d 100644 --- a/hw/bsp/imxrt/family.c +++ b/hw/bsp/imxrt/family.c @@ -40,6 +40,7 @@ #include "fsl_iomuxc.h" #include "fsl_clock.h" #include "fsl_lpuart.h" +#include "fsl_ocotp.h" #ifdef __GNUC__ #pragma GCC diagnostic pop @@ -186,6 +187,29 @@ uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN); } +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + + #if FSL_FEATURE_OCOTP_HAS_TIMING_CTRL + OCOTP_Init(OCOTP, CLOCK_GetFreq(kCLOCK_IpgClk)); + #else + OCOTP_Init(OCOTP, 0u); + #endif + + // Reads shadow registers 0x01 - 0x04 (Configuration and Manufacturing Info) + // into 8 bit wide destination, avoiding punning. + for (int i = 0; i < 4; ++i) { + uint32_t wr = OCOTP_ReadFuseShadowRegister(OCOTP, i + 1); + for (int j = 0; j < 4; j++) { + id[i*4+j] = wr & 0xff; + wr >>= 8; + } + } + OCOTP_Deinit(OCOTP); + + return 16; +} + int board_uart_read(uint8_t* buf, int len) { int count = 0; diff --git a/hw/bsp/imxrt/family.cmake b/hw/bsp/imxrt/family.cmake index f4d7378a5..d917e9777 100644 --- a/hw/bsp/imxrt/family.cmake +++ b/hw/bsp/imxrt/family.cmake @@ -44,6 +44,7 @@ function(add_board_target BOARD_TARGET) ${SDK_DIR}/drivers/igpio/fsl_gpio.c ${SDK_DIR}/drivers/lpspi/fsl_lpspi.c ${SDK_DIR}/drivers/lpuart/fsl_lpuart.c + ${SDK_DIR}/drivers/ocotp/fsl_ocotp.c ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT_WITH_CORE}.c ${SDK_DIR}/devices/${MCU_VARIANT}/xip/fsl_flexspi_nor_boot.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c @@ -75,6 +76,7 @@ function(add_board_target BOARD_TARGET) ${SDK_DIR}/drivers/igpio ${SDK_DIR}/drivers/lpspi ${SDK_DIR}/drivers/lpuart + ${SDK_DIR}/drivers/ocotp ) update_board(${BOARD_TARGET}) -- cgit v1.3.1 From 68518aaa4b352c2879da61083bf72455c019ef36 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 18 Jul 2024 09:25:52 +0700 Subject: add metro_m7_1011 to hil rpi --- test/hil/rpi.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/hil/rpi.json b/test/hil/rpi.json index c9a77936d..338ecae20 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -30,6 +30,13 @@ "flasher": "esptool", "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", "flasher_args": "-b 1500000" + }, + { + "name": "metro_m7_1011", + "uid": "9CE8715DD71137363E00005002004200", + "flasher": "jlink", + "flasher_sn": "000611000000", + "flasher_args": "-device MIMXRT1011xxx5A" } ] } -- cgit v1.3.1 From 8be0d503dab57be6af0cd8aea2df41588b40fc55 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 18 Jul 2024 09:34:58 +0700 Subject: fix make build --- hw/bsp/imxrt/family.mk | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/bsp/imxrt/family.mk b/hw/bsp/imxrt/family.mk index bde4c4ba6..f00afb6a4 100644 --- a/hw/bsp/imxrt/family.mk +++ b/hw/bsp/imxrt/family.mk @@ -50,7 +50,8 @@ SRC_C += \ $(SDK_DIR)/drivers/common/fsl_common.c \ $(SDK_DIR)/drivers/common/fsl_common_arm.c \ $(SDK_DIR)/drivers/igpio/fsl_gpio.c \ - $(SDK_DIR)/drivers/lpuart/fsl_lpuart.c + $(SDK_DIR)/drivers/lpuart/fsl_lpuart.c \ + $(SDK_DIR)/drivers/ocotp/fsl_ocotp.c \ # Optional drivers: only available for some mcus: rt1160, rt1170 ifneq (,$(wildcard ${TOP}/${MCU_DIR}/drivers/fsl_dcdc.c)) @@ -68,7 +69,8 @@ INC += \ $(TOP)/$(MCU_DIR)/drivers \ $(TOP)/$(SDK_DIR)/drivers/common \ $(TOP)/$(SDK_DIR)/drivers/igpio \ - $(TOP)/$(SDK_DIR)/drivers/lpuart + $(TOP)/$(SDK_DIR)/drivers/lpuart \ + $(TOP)/$(SDK_DIR)/drivers/ocotp \ SRC_S += $(MCU_DIR)/gcc/startup_$(MCU_VARIANT_WITH_CORE).S -- cgit v1.3.1 From 30a48c57bd2f56d38c846e1f3257b2bde9ab4a9c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 18 Jul 2024 13:21:38 +0700 Subject: fix hil board_test duplication, add cdc_msc_freertos test --- examples/device/cdc_msc_freertos/src/msc_disk.c | 24 +++++++++++++++++++++++- test/hil/hil_test.py | 13 +++++++------ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/examples/device/cdc_msc_freertos/src/msc_disk.c b/examples/device/cdc_msc_freertos/src/msc_disk.c index c8a04bb74..d2f8628f1 100644 --- a/examples/device/cdc_msc_freertos/src/msc_disk.c +++ b/examples/device/cdc_msc_freertos/src/msc_disk.c @@ -28,6 +28,9 @@ #if CFG_TUD_MSC +// whether host does safe-eject +static bool ejected = false; + // Some MCU doesn't have enough 8KB SRAM to store the whole disk // We will use Flash as read-only disk with board that has // CFG_EXAMPLE_MSC_READONLY defined @@ -137,7 +140,14 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun) { (void) lun; - return true; // RAM disk is always ready + // RAM disk is ready until ejected + if (ejected) { + // Additional Sense 3A-00 is NOT_FOUND + tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00); + return false; + } + + return true; } // Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size @@ -166,6 +176,7 @@ bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, boo }else { // unload disk storage + ejected = true; } } @@ -187,6 +198,17 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff return (int32_t) bufsize; } +bool tud_msc_is_writable_cb (uint8_t lun) +{ + (void) lun; + +#ifdef CFG_EXAMPLE_MSC_READONLY + return false; +#else + return true; +#endif +} + // Callback invoked when received WRITE10 command. // Process data in buffer to disk's storage and return number of written bytes int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index f571e6e02..87cf5d0f6 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -335,9 +335,13 @@ def main(): with open(config_file) as f: config = json.load(f) - # all possible tests + # all possible tests: board_test is added last to disable board's usb all_tests = [ - 'cdc_dual_ports', 'cdc_msc', 'dfu', 'dfu_runtime', 'hid_boot_interface', + 'cdc_dual_ports', + 'cdc_msc', 'cdc_msc_freertos', + 'dfu', 'dfu_runtime', + 'hid_boot_interface', + 'board_test' ] if len(boards) == 0: @@ -352,13 +356,10 @@ def main(): # default to all tests if 'tests' in item: - test_list = item['tests'] + test_list = item['tests'] + ['board_test'] else: test_list = all_tests - # board_test is added last to disable board's usb - test_list.append('board_test') - # remove skip_tests if 'tests_skip' in item: for skip in item['tests_skip']: -- cgit v1.3.1 From eb698f8cc7ec2ca84051c0ce3bb6e845f8f8407d Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 18 Jul 2024 13:54:11 +0700 Subject: skip hil test if binary not exist --- test/hil/hil_test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 87cf5d0f6..8f0a8c93a 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -373,6 +373,10 @@ def main(): fw_name = f'{fw_dir}/{test}' print(f' {test} ...', end='') + if not os.path.exists(fw_dir): + print('Skip') + continue + # flash firmware. It may fail randomly, retry a few times for i in range(3): ret = globals()[f'flash_{flasher}'](item, fw_name) -- cgit v1.3.1 From 23c9353cd86bcecd9d1220bbb2277d5ffb834e7c Mon Sep 17 00:00:00 2001 From: Liam Fraser Date: Thu, 18 Jul 2024 11:08:23 +0100 Subject: net_lwip_webserver: allow TINYUSB_LWIP_PATH to be defined by parent CMake file --- examples/device/net_lwip_webserver/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/device/net_lwip_webserver/CMakeLists.txt b/examples/device/net_lwip_webserver/CMakeLists.txt index c39fd32c5..13923b583 100644 --- a/examples/device/net_lwip_webserver/CMakeLists.txt +++ b/examples/device/net_lwip_webserver/CMakeLists.txt @@ -5,7 +5,14 @@ include(${CMAKE_CURRENT_LIST_DIR}/../../../hw/bsp/family_support.cmake) # gets PROJECT name for the example (e.g. -) family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) +# Prefer the tinyusb lwip set(LWIP ${TOP}/lib/lwip) + +# If we can't find one from tinyusb then check cmake var before giving up +if (NOT EXISTS ${LWIP}/src) + set(LWIP ${TINYUSB_LWIP_PATH}) +endif() + if (NOT EXISTS ${LWIP}/src) family_example_missing_dependency(${PROJECT} "lib/lwip") return() -- cgit v1.3.1 From 0d72f153cf1614aaff0b5859d00fb5c0e1711f51 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Wed, 17 Jul 2024 15:46:35 -0500 Subject: fix arguable bug caught as warning by LLVM embedded toolchain for ARM 14.0.0 --- src/tusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tusb.c b/src/tusb.c index 0092267a1..860e8ac35 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -398,7 +398,7 @@ static void dump_str_line(uint8_t const* buf, uint16_t count) { tu_printf(" |"); // each line is 16 bytes for (uint16_t i = 0; i < count; i++) { - const char ch = buf[i]; + int ch = buf[i]; tu_printf("%c", isprint(ch) ? ch : '.'); } tu_printf("|\r\n"); -- cgit v1.3.1 From 5f6152a87e2a2fd07ed0cdbf6cf2300cb4fc6342 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Wed, 17 Jul 2024 20:03:27 -0500 Subject: not all GCC compiler builds support --no-warn-rwx-segments; check_linker_flag is not available in all supported version of CMake, so just allow it to be passed in --- hw/bsp/family_support.cmake | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index bc2d481bb..6a1e96624 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -69,6 +69,10 @@ if (NOT FAMILY STREQUAL rp2040) endif() endif() +if (NOT NO_WARN_RWX_SEGMENTS_SUPPORTED) + set(NO_WARN_RWX_SEGMENTS_SUPPORTED 1) +endif() + set(WARNING_FLAGS_GNU -Wall -Wextra @@ -210,7 +214,7 @@ function(family_configure_common TARGET RTOS) # Generate linker map file if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:-Map=$.map") - if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0) + if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0 AND NO_WARN_RWX_SEGMENTS_SUPPORTED) target_link_options(${TARGET} PUBLIC "LINKER:--no-warn-rwx-segments") endif () elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") @@ -360,7 +364,7 @@ function(family_add_default_example_warnings TARGET) ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0) + if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0 AND NO_WARN_RWX_SEGMENTS_SUPPORTED) target_link_options(${TARGET} PUBLIC "LINKER:--no-warn-rwx-segments") endif() -- cgit v1.3.1 From 31a979a6cccc2d4dc0a86474643710ae3b7f34fe Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Wed, 17 Jul 2024 21:08:55 -0500 Subject: fix some clang compiler warnings --- examples/host/cdc_msc_hid/src/hid_app.c | 1 + examples/host/hid_controller/src/hid_app.c | 1 + src/class/hid/hid_host.c | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/host/cdc_msc_hid/src/hid_app.c b/examples/host/cdc_msc_hid/src/hid_app.c index f0d42a08f..6bb3a2072 100644 --- a/examples/host/cdc_msc_hid/src/hid_app.c +++ b/examples/host/cdc_msc_hid/src/hid_app.c @@ -235,6 +235,7 @@ static void process_mouse_report(hid_mouse_report_t const * report) static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) { (void) dev_addr; + (void) len; uint8_t const rpt_count = hid_info[instance].report_count; tuh_hid_report_info_t* rpt_info_arr = hid_info[instance].report_info; diff --git a/examples/host/hid_controller/src/hid_app.c b/examples/host/hid_controller/src/hid_app.c index bff830ca2..6ffe0b6d4 100644 --- a/examples/host/hid_controller/src/hid_app.c +++ b/examples/host/hid_controller/src/hid_app.c @@ -253,6 +253,7 @@ bool diff_report(sony_ds4_report_t const* rpt1, sony_ds4_report_t const* rpt2) void process_sony_ds4(uint8_t const* report, uint16_t len) { + (void)len; const char* dpad_str[] = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "none" }; // previous report used to compare for changes diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 115a8a4df..7639a8fc6 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -657,7 +657,9 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr, uint8_t const data8 = desc_report[0]; TU_LOG(3, "tag = %d, type = %d, size = %d, data = ", tag, type, size); - for (uint32_t i = 0; i < size; i++) TU_LOG(3, "%02X ", desc_report[i]); + for (uint32_t i = 0; i < size; i++) { + TU_LOG(3, "%02X ", desc_report[i]); + } TU_LOG(3, "\r\n"); switch (type) { -- cgit v1.3.1 From ffe1d0664b6abe942c14ca540833e1e86a797184 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 18 Jul 2024 20:02:57 +0200 Subject: UAC2: Fix memclr on driver reset. --- src/class/audio/audio_device.c | 94 ++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 44 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 65cac2fd5..ed380424f 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -304,19 +304,6 @@ typedef struct uint16_t desc_length; // Length of audio function descriptor - // Buffer for control requests - uint8_t * ctrl_buf; - uint8_t ctrl_buf_sz; - - // Current active alternate settings - uint8_t * alt_setting; // We need to save the current alternate setting this way, because it is possible that there are AS interfaces which do not have an EP! - - // EP Transfer buffers and FIFOs -#if CFG_TUD_AUDIO_ENABLE_EP_OUT -#if !CFG_TUD_AUDIO_ENABLE_DECODING - tu_fifo_t ep_out_ff; -#endif - #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP struct { CFG_TUSB_MEM_ALIGN uint32_t value; // Feedback value for asynchronous mode (in 16.16 format). @@ -346,17 +333,6 @@ typedef struct } feedback; #endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT - -#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING - tu_fifo_t ep_in_ff; -#endif - - // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) -#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP - CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf[6]; -#endif - // Decoding parameters - parameters are set when alternate AS interface is set by host // Coding is currently only supported for EP. Software coding corresponding to AS interfaces without EPs are not supported currently. #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING @@ -365,8 +341,7 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING audio_data_format_type_I_t format_type_I_rx; - uint8_t n_bytes_per_sampe_rx; - uint8_t n_channels_per_ff_rx; + uint8_t n_bytes_per_sample_rx; uint8_t n_ff_used_rx; #endif #endif @@ -382,26 +357,57 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_EP_IN && (CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL) audio_format_type_t format_type_tx; uint8_t n_channels_tx; - uint8_t n_bytes_per_sampe_tx; + uint8_t n_bytes_per_sample_tx; #if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING audio_data_format_type_I_t format_type_I_tx; - uint8_t n_channels_per_ff_tx; uint8_t n_ff_used_tx; #endif #endif + // Buffer for control requests + uint8_t * ctrl_buf; + uint8_t ctrl_buf_sz; + + // Current active alternate settings + uint8_t * alt_setting; // We need to save the current alternate setting this way, because it is possible that there are AS interfaces which do not have an EP! + + // EP Transfer buffers and FIFOs +#if CFG_TUD_AUDIO_ENABLE_EP_OUT +#if !CFG_TUD_AUDIO_ENABLE_DECODING + tu_fifo_t ep_out_ff; +#endif + + +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT + +#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING + tu_fifo_t ep_in_ff; +#endif + + // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP + CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf[6]; +#endif + + // Support FIFOs for software encoding and decoding #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING tu_fifo_t * rx_supp_ff; uint8_t n_rx_supp_ff; uint16_t rx_supp_ff_sz_max; +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING + uint8_t n_channels_per_ff_rx; +#endif #endif #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING tu_fifo_t * tx_supp_ff; uint8_t n_tx_supp_ff; uint16_t tx_supp_ff_sz_max; +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING + uint8_t n_channels_per_ff_tx; +#endif #endif // Linear buffer in case target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer is available or driver is would need to be changed dramatically OR the support FIFOs are used @@ -707,16 +713,16 @@ static bool audiod_decode_type_I_pcm(uint8_t rhport, audiod_function_t* audio, u if (info.len_lin != 0) { info.len_lin = tu_min16(nBytesPerFFToRead, info.len_lin); - src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sampe_rx]; + src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sample_rx]; dst_end = info.ptr_lin + info.len_lin; - src = audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sampe_rx, info.ptr_lin, dst_end, src, n_ff_used); + src = audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sample_rx, info.ptr_lin, dst_end, src, n_ff_used); // Handle wrapped part of FIFO info.len_wrap = tu_min16(nBytesPerFFToRead - info.len_lin, info.len_wrap); if (info.len_wrap != 0) { dst_end = info.ptr_wrap + info.len_wrap; - audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sampe_rx, info.ptr_wrap, dst_end, src, n_ff_used); + audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sample_rx, info.ptr_wrap, dst_end, src, n_ff_used); } tu_fifo_advance_write_pointer(&audio->rx_supp_ff[cnt_ff], info.len_lin + info.len_wrap); } @@ -1024,7 +1030,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi // Limit to maximum sample number - THIS IS A POSSIBLE ERROR SOURCE IF TOO MANY SAMPLE WOULD NEED TO BE SENT BUT CAN NOT! nBytesPerFFToSend = tu_min16(nBytesPerFFToSend, audio->ep_in_sz / n_ff_used); // Round to full number of samples (flooring) - uint16_t const nSlotSize = audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx; + uint16_t const nSlotSize = audio->n_channels_per_ff_tx * audio->n_bytes_per_sample_tx; nBytesPerFFToSend = (nBytesPerFFToSend / nSlotSize) * nSlotSize; #endif @@ -1036,7 +1042,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++) { - dst = &audio->lin_buf_in[cnt_ff*audio->n_channels_per_ff_tx*audio->n_bytes_per_sampe_tx]; + dst = &audio->lin_buf_in[cnt_ff*audio->n_channels_per_ff_tx*audio->n_bytes_per_sample_tx]; tu_fifo_get_read_info(&audio->tx_supp_ff[cnt_ff], &info); @@ -1044,7 +1050,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi { info.len_lin = tu_min16(nBytesPerFFToSend, info.len_lin); // Limit up to desired length src_end = (uint8_t *)info.ptr_lin + info.len_lin; - dst = audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sampe_tx, info.ptr_lin, src_end, dst, n_ff_used); + dst = audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sample_tx, info.ptr_lin, src_end, dst, n_ff_used); // Limit up to desired length info.len_wrap = tu_min16(nBytesPerFFToSend - info.len_lin, info.len_wrap); @@ -1053,7 +1059,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi if (info.len_wrap != 0) { src_end = (uint8_t *)info.ptr_wrap + info.len_wrap; - audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sampe_tx, info.ptr_wrap, src_end, dst, n_ff_used); + audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sample_tx, info.ptr_wrap, src_end, dst, n_ff_used); } tu_fifo_advance_read_pointer(&audio->tx_supp_ff[cnt_ff], info.len_lin + info.len_wrap); @@ -1782,8 +1788,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap #if CFG_TUD_AUDIO_ENABLE_ENCODING && CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING - const uint16_t active_fifo_depth = (uint16_t) ((audio->tx_supp_ff_sz_max / (audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx)) - * (audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx)); + const uint16_t active_fifo_depth = (uint16_t) ((audio->tx_supp_ff_sz_max / (audio->n_channels_per_ff_tx * audio->n_bytes_per_sample_tx)) + * (audio->n_channels_per_ff_tx * audio->n_bytes_per_sample_tx)); for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++) { tu_fifo_config(&audio->tx_supp_ff[cnt], audio->tx_supp_ff[cnt].buffer, active_fifo_depth, 1, true); @@ -1813,7 +1819,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap #if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING - const uint16_t active_fifo_depth = (audio->rx_supp_ff_sz_max / audio->n_bytes_per_sampe_rx) * audio->n_bytes_per_sampe_rx; + const uint16_t active_fifo_depth = (audio->rx_supp_ff_sz_max / audio->n_bytes_per_sample_rx) * audio->n_bytes_per_sample_rx; for (uint8_t cnt = 0; cnt < audio->n_rx_supp_ff; cnt++) { tu_fifo_config(&audio->rx_supp_ff[cnt], audio->rx_supp_ff[cnt].buffer, active_fifo_depth, 1, true); @@ -2587,14 +2593,14 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #if CFG_TUD_AUDIO_ENABLE_EP_IN if (as_itf == audio->ep_in_as_intf_num) { - audio->n_bytes_per_sampe_tx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; + audio->n_bytes_per_sample_tx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; } #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING if (as_itf == audio->ep_out_as_intf_num) { - audio->n_bytes_per_sampe_rx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; + audio->n_bytes_per_sample_rx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; } #endif } @@ -2613,7 +2619,7 @@ static bool audiod_calc_tx_packet_sz(audiod_function_t* audio) { TU_VERIFY(audio->format_type_tx == AUDIO_FORMAT_TYPE_I); TU_VERIFY(audio->n_channels_tx); - TU_VERIFY(audio->n_bytes_per_sampe_tx); + TU_VERIFY(audio->n_bytes_per_sample_tx); TU_VERIFY(audio->interval_tx); TU_VERIFY(audio->sample_rate_tx); @@ -2622,9 +2628,9 @@ static bool audiod_calc_tx_packet_sz(audiod_function_t* audio) const uint16_t sample_normimal = (uint16_t)(audio->sample_rate_tx * interval / ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000)); const uint16_t sample_reminder = (uint16_t)(audio->sample_rate_tx * interval % ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000)); - const uint16_t packet_sz_tx_min = (uint16_t)((sample_normimal - 1) * audio->n_channels_tx * audio->n_bytes_per_sampe_tx); - const uint16_t packet_sz_tx_norm = (uint16_t)(sample_normimal * audio->n_channels_tx * audio->n_bytes_per_sampe_tx); - const uint16_t packet_sz_tx_max = (uint16_t)((sample_normimal + 1) * audio->n_channels_tx * audio->n_bytes_per_sampe_tx); + const uint16_t packet_sz_tx_min = (uint16_t)((sample_normimal - 1) * audio->n_channels_tx * audio->n_bytes_per_sample_tx); + const uint16_t packet_sz_tx_norm = (uint16_t)(sample_normimal * audio->n_channels_tx * audio->n_bytes_per_sample_tx); + const uint16_t packet_sz_tx_max = (uint16_t)((sample_normimal + 1) * audio->n_channels_tx * audio->n_bytes_per_sample_tx); // Endpoint size must larger than packet size TU_ASSERT(packet_sz_tx_max <= audio->ep_in_sz); -- cgit v1.3.1 From 94454684f78a528c343e306d723e6c8d2b05e932 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jul 2024 11:29:48 +0700 Subject: add ra4m1 ek for hil test --- .idea/cmake.xml | 14 +++++++------- hw/bsp/ra/family.c | 8 +++++++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index ec900b4a6..f09e185b1 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -66,14 +66,14 @@ - + - + @@ -106,11 +106,11 @@ - - - - - + + + + + diff --git a/hw/bsp/ra/family.c b/hw/bsp/ra/family.c index db8988a36..a8b4ebcc7 100644 --- a/hw/bsp/ra/family.c +++ b/hw/bsp/ra/family.c @@ -147,6 +147,13 @@ uint32_t board_button_read(void) { return lvl == BUTTON_STATE_ACTIVE; } +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + max_len = tu_min32(max_len, sizeof(bsp_unique_id_t)); + bsp_unique_id_t const *uid = R_BSP_UniqueIdGet(); + memcpy(id, uid->unique_id_bytes, max_len); + return max_len; +} + int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; @@ -169,7 +176,6 @@ void SysTick_Handler(void) { uint32_t board_millis(void) { return system_ticks; } - #endif //--------------------------------------------------------------------+ -- cgit v1.3.1 From 7e7a38b97d6f8abbdff029c6bf24c52bf53f5910 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jul 2024 11:48:43 +0700 Subject: update test json --- test/hil/rpi.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 338ecae20..44edb7de0 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -37,6 +37,13 @@ "flasher": "jlink", "flasher_sn": "000611000000", "flasher_args": "-device MIMXRT1011xxx5A" + }, + { + "name": "ra4m1_ek", + "uid": "152E163038303131393346E46F26574B", + "flasher": "jlink", + "flasher_sn": "000831174392", + "flasher_args": "-device R7FA4M1AB" } ] } -- cgit v1.3.1 From b35173b5b0051e4e2d168918b2e5e14604725888 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jul 2024 12:12:26 +0700 Subject: skip msc tests for ra due to existing bug --- test/hil/hil_test.py | 2 +- test/hil/rpi.json | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 8f0a8c93a..158841687 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -358,7 +358,7 @@ def main(): if 'tests' in item: test_list = item['tests'] + ['board_test'] else: - test_list = all_tests + test_list = list(all_tests) # remove skip_tests if 'tests_skip' in item: diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 44edb7de0..98d576db8 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -41,6 +41,8 @@ { "name": "ra4m1_ek", "uid": "152E163038303131393346E46F26574B", + "tests_skip": ["cdc_msc", "cdc_msc_freertos"], + "comment": "MSC is slow to enumerated #2602", "flasher": "jlink", "flasher_sn": "000831174392", "flasher_args": "-device R7FA4M1AB" -- cgit v1.3.1 From 60b3d14d1979b4a281f999e3a1861b44477f57b1 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 8 May 2024 14:05:58 +0200 Subject: Check tud ready check for OUT xfer. --- src/class/cdc/cdc_device.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 681a1b852..792aedf26 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -81,8 +81,13 @@ typedef struct { CFG_TUD_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; static tud_cdc_configure_fifo_t _cdcd_fifo_cfg; -static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { +static bool _prep_out_transaction (cdcd_interface_t* p_cdc, bool itf_open) +{ uint8_t const rhport = 0; + + // Skip if usb is not ready yet + TU_VERIFY(tud_ready() || itf_open); + uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff); // Prepare for incoming data but only allow what we can store in the ring buffer. @@ -143,7 +148,7 @@ uint32_t tud_cdc_n_available(uint8_t itf) { uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); - _prep_out_transaction(p_cdc); + _prep_out_transaction(p_cdc, false); return num_read; } @@ -154,7 +159,7 @@ bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) { void tud_cdc_n_read_flush(uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; tu_fifo_clear(&p_cdc->rx_ff); - _prep_out_transaction(p_cdc); + _prep_out_transaction(p_cdc, false); } //--------------------------------------------------------------------+ @@ -336,7 +341,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 } // Prepare for incoming data - _prep_out_transaction(p_cdc); + _prep_out_transaction(p_cdc, true); return drv_len; } @@ -445,7 +450,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff)) tud_cdc_rx_cb(itf); // prepare for OUT transaction - _prep_out_transaction(p_cdc); + _prep_out_transaction(p_cdc, false); } // Data sent to host, we continue to fetch from tx fifo to send. -- cgit v1.3.1 From a1fd43ebaf0a36683c0437ea258e2a024341ef6d Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 8 May 2024 14:07:32 +0200 Subject: Clear _usbd_dev prior to driver reset. --- src/device/usbd.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 4105a71a4..b2fd54575 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -495,15 +495,16 @@ bool tud_deinit(uint8_t rhport) { } static void configuration_reset(uint8_t rhport) { + // Clear mounted status first to ensure tud_ready() return false before driver clean up. + tu_varclr(&_usbd_dev); + memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping + memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); TU_ASSERT(driver,); driver->reset(rhport); } - - tu_varclr(&_usbd_dev); - memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping - memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping } static void usbd_reset(uint8_t rhport) { -- cgit v1.3.1 From 772398f6ead893e6eb69399e11c725919c2f1e1a Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 8 May 2024 20:03:45 +0200 Subject: Save setup_count on bus reset. --- src/device/usbd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/device/usbd.c b/src/device/usbd.c index b2fd54575..2735e35fd 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -495,10 +495,13 @@ bool tud_deinit(uint8_t rhport) { } static void configuration_reset(uint8_t rhport) { + // Save setup_count for restore + uint8_t setup_count = _usbd_dev.setup_count; // Clear mounted status first to ensure tud_ready() return false before driver clean up. tu_varclr(&_usbd_dev); memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping + _usbd_dev.setup_count = setup_count; for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); -- cgit v1.3.1 From 4b55af17c90acad9c03f5f3b41645d4ed954d42f Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 17:10:44 +0200 Subject: Fix STM32F7 FS port build. --- hw/bsp/stm32f7/family.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/bsp/stm32f7/family.mk b/hw/bsp/stm32f7/family.mk index e261b0467..bae7d6d5b 100644 --- a/hw/bsp/stm32f7/family.mk +++ b/hw/bsp/stm32f7/family.mk @@ -24,6 +24,7 @@ ifeq ($(PORT), 1) $(info "Using OTG_HS in FullSpeed mode") endif else + CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED $(info "Using OTG_FS") endif -- cgit v1.3.1 From be18af823591389a12e246f65784646f93443882 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jul 2024 17:10:53 +0700 Subject: revert changes to usbds configuration_reset() (deal with it in separated PR) --- src/class/cdc/cdc_device.c | 3 +-- src/device/usbd.c | 12 ++++-------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 792aedf26..570c825ab 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -81,8 +81,7 @@ typedef struct { CFG_TUD_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; static tud_cdc_configure_fifo_t _cdcd_fifo_cfg; -static bool _prep_out_transaction (cdcd_interface_t* p_cdc, bool itf_open) -{ +static bool _prep_out_transaction (cdcd_interface_t* p_cdc, bool itf_open) { uint8_t const rhport = 0; // Skip if usb is not ready yet diff --git a/src/device/usbd.c b/src/device/usbd.c index 2735e35fd..4105a71a4 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -495,19 +495,15 @@ bool tud_deinit(uint8_t rhport) { } static void configuration_reset(uint8_t rhport) { - // Save setup_count for restore - uint8_t setup_count = _usbd_dev.setup_count; - // Clear mounted status first to ensure tud_ready() return false before driver clean up. - tu_varclr(&_usbd_dev); - memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping - memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping - _usbd_dev.setup_count = setup_count; - for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); TU_ASSERT(driver,); driver->reset(rhport); } + + tu_varclr(&_usbd_dev); + memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping + memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping } static void usbd_reset(uint8_t rhport) { -- cgit v1.3.1 From 6fb6602a097b2d2e026f150d6fde387803606f88 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jul 2024 18:08:04 +0700 Subject: - add tud_cdc_n_ready() though not used - usbd now change _usbd_dev.cfg_num before calling driver's open() --- src/class/cdc/cdc_device.c | 16 ++++++++++------ src/class/cdc/cdc_device.h | 8 ++++++++ src/common/tusb_verify.h | 10 +++++----- src/device/usbd.c | 10 ++++++++-- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 570c825ab..ebc408f5a 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -81,11 +81,11 @@ typedef struct { CFG_TUD_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; static tud_cdc_configure_fifo_t _cdcd_fifo_cfg; -static bool _prep_out_transaction (cdcd_interface_t* p_cdc, bool itf_open) { +static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { uint8_t const rhport = 0; // Skip if usb is not ready yet - TU_VERIFY(tud_ready() || itf_open); + TU_VERIFY(tud_ready() && p_cdc->ep_out); uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff); @@ -120,6 +120,10 @@ bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg) { return true; } +bool tud_cdc_n_ready(uint8_t itf) { + return tud_ready() && _cdcd_itf[itf].ep_in != 0 && _cdcd_itf[itf].ep_out != 0; +} + bool tud_cdc_n_connected(uint8_t itf) { // DTR (bit 0) active is considered as connected return tud_ready() && tu_bit_test(_cdcd_itf[itf].line_state, 0); @@ -147,7 +151,7 @@ uint32_t tud_cdc_n_available(uint8_t itf) { uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); - _prep_out_transaction(p_cdc, false); + _prep_out_transaction(p_cdc); return num_read; } @@ -158,7 +162,7 @@ bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) { void tud_cdc_n_read_flush(uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; tu_fifo_clear(&p_cdc->rx_ff); - _prep_out_transaction(p_cdc, false); + _prep_out_transaction(p_cdc); } //--------------------------------------------------------------------+ @@ -340,7 +344,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 } // Prepare for incoming data - _prep_out_transaction(p_cdc, true); + _prep_out_transaction(p_cdc); return drv_len; } @@ -449,7 +453,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff)) tud_cdc_rx_cb(itf); // prepare for OUT transaction - _prep_out_transaction(p_cdc, false); + _prep_out_transaction(p_cdc); } // Data sent to host, we continue to fetch from tx fifo to send. diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 34670517a..3ad7c8baf 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -61,6 +61,9 @@ bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg); // Application API (Multiple Ports) i.e. CFG_TUD_CDC > 1 //--------------------------------------------------------------------+ +// Check if interface is ready +bool tud_cdc_n_ready(uint8_t itf); + // Check if terminal is connected to this port bool tud_cdc_n_connected(uint8_t itf); @@ -116,6 +119,11 @@ bool tud_cdc_n_write_clear(uint8_t itf); //--------------------------------------------------------------------+ // Application API (Single Port) //--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_ready(void) { + return tud_cdc_n_ready(0); +} + TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_connected(void) { return tud_cdc_n_connected(0); } diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index dde0550d3..4344575b7 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -56,8 +56,8 @@ * #define TU_VERIFY(cond) if(cond) return false; * #define TU_VERIFY(cond,ret) if(cond) return ret; * - * #define TU_ASSERT(cond) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return false;} - * #define TU_ASSERT(cond,ret) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return ret;} + * #define TU_ASSERT(cond) if(cond) {TU_MESS_FAILED(); TU_BREAKPOINT(), return false;} + * #define TU_ASSERT(cond,ret) if(cond) {TU_MESS_FAILED(); TU_BREAKPOINT(), return ret;} *------------------------------------------------------------------*/ #ifdef __cplusplus @@ -70,9 +70,9 @@ #if CFG_TUSB_DEBUG #include - #define _MESS_FAILED() tu_printf("%s %d: ASSERT FAILED\r\n", __func__, __LINE__) + #define TU_MESS_FAILED() tu_printf("%s %d: ASSERT FAILED\r\n", __func__, __LINE__) #else - #define _MESS_FAILED() do {} while (0) + #define TU_MESS_FAILED() do {} while (0) #endif // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33. M55 @@ -119,7 +119,7 @@ *------------------------------------------------------------------*/ #define TU_ASSERT_DEFINE(_cond, _ret) \ do { \ - if ( !(_cond) ) { _MESS_FAILED(); TU_BREAKPOINT(); return _ret; } \ + if ( !(_cond) ) { TU_MESS_FAILED(); TU_BREAKPOINT(); return _ret; } \ } while(0) #define TU_ASSERT_1ARGS(_cond) TU_ASSERT_DEFINE(_cond, false) diff --git a/src/device/usbd.c b/src/device/usbd.c index 4105a71a4..4e723c8b9 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -747,17 +747,23 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const _usbd_dev.speed = speed; // restore speed } + _usbd_dev.cfg_num = cfg_num; + // Handle the new configuration and execute the corresponding callback if ( cfg_num ) { // switch to new configuration if not zero - TU_ASSERT( process_set_config(rhport, cfg_num) ); + if (!process_set_config(rhport, cfg_num)) { + TU_MESS_FAILED(); + TU_BREAKPOINT(); + _usbd_dev.cfg_num = 0; + return false; + } if ( tud_mount_cb ) tud_mount_cb(); } else { if ( tud_umount_cb ) tud_umount_cb(); } } - _usbd_dev.cfg_num = cfg_num; tud_control_status(rhport, p_request); } break; -- cgit v1.3.1 From d040644b6cb055532de7d3da3477e20067f1f15f Mon Sep 17 00:00:00 2001 From: Frank Voorburg Date: Sat, 29 Jun 2024 14:25:02 +0200 Subject: Additional fix related to issue #1018. Corrects the usage of TU_ATTR_WEAK for the Keil compiler for the callback functions: * tud_descriptor_bos_cb() * tud_vendor_control_xfer_cb() * tud_mount_cb() * tud_umount_cb() * tud_suspend_cb() * tud_resume_cb() Without the fix for the first two functions, the USB device won't enumerate properly, if the device makes use of a BOS description. For example when using a Microsoft OS 2.0 platform capability descriptor to set a specific Device Interface GUID for WinUSB. The fix for the other four functions were added, because it's probably just a matter of time before someone runs into the same problem with those callback functions. --- src/device/usbd.c | 34 +++++++++++++++++++++++++++++----- src/device/usbd.h | 12 ++++++------ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 4e723c8b9..719183521 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -55,6 +55,30 @@ TU_ATTR_WEAK void tud_sof_cb(uint32_t frame_count) { (void)frame_count; } +TU_ATTR_WEAK uint8_t const * tud_descriptor_bos_cb(void) { + return NULL; +} + +TU_ATTR_WEAK void tud_mount_cb(void) { +} + +TU_ATTR_WEAK void tud_umount_cb(void) { +} + +TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en) { + (void)remote_wakeup_en; +} + +TU_ATTR_WEAK void tud_resume_cb(void) { +} + +TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { + (void)rhport; + (void)stage; + (void)request; + return false; +} + TU_ATTR_WEAK bool dcd_deinit(uint8_t rhport) { (void) rhport; return false; @@ -557,7 +581,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { case DCD_EVENT_UNPLUGGED: TU_LOG_USBD("\r\n"); usbd_reset(event.rhport); - if (tud_umount_cb) tud_umount_cb(); + tud_umount_cb(); break; case DCD_EVENT_SETUP_RECEIVED: @@ -617,7 +641,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { // e.g suspend -> resume -> unplug/plug. Skip suspend/resume if not connected if (_usbd_dev.connected) { TU_LOG_USBD(": Remote Wakeup = %u\r\n", _usbd_dev.remote_wakeup_en); - if (tud_suspend_cb) tud_suspend_cb(_usbd_dev.remote_wakeup_en); + tud_suspend_cb(_usbd_dev.remote_wakeup_en); } else { TU_LOG_USBD(" Skipped\r\n"); } @@ -626,7 +650,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { case DCD_EVENT_RESUME: if (_usbd_dev.connected) { TU_LOG_USBD("\r\n"); - if (tud_resume_cb) tud_resume_cb(); + tud_resume_cb(); } else { TU_LOG_USBD(" Skipped\r\n"); } @@ -758,9 +782,9 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const _usbd_dev.cfg_num = 0; return false; } - if ( tud_mount_cb ) tud_mount_cb(); + tud_mount_cb(); } else { - if ( tud_umount_cb ) tud_umount_cb(); + tud_umount_cb(); } } diff --git a/src/device/usbd.h b/src/device/usbd.h index e47f674ea..042f2b089 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -126,7 +126,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid); // Invoked when received GET BOS DESCRIPTOR request // Application return pointer to descriptor -TU_ATTR_WEAK uint8_t const * tud_descriptor_bos_cb(void); +uint8_t const * tud_descriptor_bos_cb(void); // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. @@ -140,17 +140,17 @@ TU_ATTR_WEAK uint8_t const* tud_descriptor_device_qualifier_cb(void); TU_ATTR_WEAK uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index); // Invoked when device is mounted (configured) -TU_ATTR_WEAK void tud_mount_cb(void); +void tud_mount_cb(void); // Invoked when device is unmounted -TU_ATTR_WEAK void tud_umount_cb(void); +void tud_umount_cb(void); // Invoked when usb bus is suspended // Within 7ms, device must draw an average of current less than 2.5 mA from bus -TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en); +void tud_suspend_cb(bool remote_wakeup_en); // Invoked when usb bus is resumed -TU_ATTR_WEAK void tud_resume_cb(void); +void tud_resume_cb(void); // Invoked when there is a new usb event, which need to be processed by tud_task()/tud_task_ext() void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); @@ -159,7 +159,7 @@ void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); void tud_sof_cb(uint32_t frame_count); // Invoked when received control request with VENDOR TYPE -TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); //--------------------------------------------------------------------+ // Binary Device Object Store (BOS) Descriptor Templates -- cgit v1.3.1 From e92acf0a91b071a723c408385add083dfe337e8b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jul 2024 20:53:23 +0700 Subject: also migrate tud_descriptor_device_qualifier_cb() / tud_descriptor_other_speed_configuration_cb() --- src/device/usbd.c | 58 ++++++++++++++++++++++++++----------------------------- src/device/usbd.h | 6 +++--- 2 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 719183521..f0d7c45b1 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -46,16 +46,25 @@ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { - (void)rhport; - (void)eventid; - (void)in_isr; + (void) rhport; + (void) eventid; + (void) in_isr; } TU_ATTR_WEAK void tud_sof_cb(uint32_t frame_count) { - (void)frame_count; + (void) frame_count; +} + +TU_ATTR_WEAK uint8_t const* tud_descriptor_bos_cb(void) { + return NULL; +} + +TU_ATTR_WEAK uint8_t const* tud_descriptor_device_qualifier_cb(void) { + return NULL; } -TU_ATTR_WEAK uint8_t const * tud_descriptor_bos_cb(void) { +TU_ATTR_WEAK uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) { + (void) index; return NULL; } @@ -66,16 +75,16 @@ TU_ATTR_WEAK void tud_umount_cb(void) { } TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en) { - (void)remote_wakeup_en; + (void) remote_wakeup_en; } TU_ATTR_WEAK void tud_resume_cb(void) { } -TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { - (void)rhport; - (void)stage; - (void)request; +TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { + (void) rhport; + (void) stage; + (void) request; return false; } @@ -1075,15 +1084,12 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const } // break; // unreachable - case TUSB_DESC_BOS: - { + case TUSB_DESC_BOS: { TU_LOG_USBD(" BOS\r\n"); // requested by host if USB > 2.0 ( i.e 2.1 or 3.x ) - if (!tud_descriptor_bos_cb) return false; - uintptr_t desc_bos = (uintptr_t) tud_descriptor_bos_cb(); - TU_ASSERT(desc_bos); + TU_VERIFY(desc_bos); // Use offsetof to avoid pointer to the odd/misaligned address uint16_t const total_len = tu_le16toh( tu_unaligned_read16((const void*) (desc_bos + offsetof(tusb_desc_bos_t, wTotalLength))) ); @@ -1093,24 +1099,20 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const // break; // unreachable case TUSB_DESC_CONFIGURATION: - case TUSB_DESC_OTHER_SPEED_CONFIG: - { + case TUSB_DESC_OTHER_SPEED_CONFIG: { uintptr_t desc_config; - if ( desc_type == TUSB_DESC_CONFIGURATION ) - { + if ( desc_type == TUSB_DESC_CONFIGURATION ) { TU_LOG_USBD(" Configuration[%u]\r\n", desc_index); desc_config = (uintptr_t) tud_descriptor_configuration_cb(desc_index); - }else - { + TU_ASSERT(desc_config); + }else { // Host only request this after getting Device Qualifier descriptor TU_LOG_USBD(" Other Speed Configuration\r\n"); - TU_VERIFY( tud_descriptor_other_speed_configuration_cb ); desc_config = (uintptr_t) tud_descriptor_other_speed_configuration_cb(desc_index); + TU_VERIFY(desc_config); } - TU_ASSERT(desc_config); - // Use offsetof to avoid pointer to the odd/misaligned address uint16_t const total_len = tu_le16toh( tu_unaligned_read16((const void*) (desc_config + offsetof(tusb_desc_configuration_t, wTotalLength))) ); @@ -1131,16 +1133,10 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const } // break; // unreachable - case TUSB_DESC_DEVICE_QUALIFIER: - { + case TUSB_DESC_DEVICE_QUALIFIER: { TU_LOG_USBD(" Device Qualifier\r\n"); - - TU_VERIFY( tud_descriptor_device_qualifier_cb ); - uint8_t const* desc_qualifier = tud_descriptor_device_qualifier_cb(); TU_VERIFY(desc_qualifier); - - // first byte of descriptor is its size return tud_control_xfer(rhport, p_request, (void*) (uintptr_t) desc_qualifier, tu_desc_len(desc_qualifier)); } // break; // unreachable diff --git a/src/device/usbd.h b/src/device/usbd.h index 042f2b089..3d3e83f41 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -109,7 +109,7 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, vo bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request); //--------------------------------------------------------------------+ -// Application Callbacks (WEAK is optional) +// Application Callbacks //--------------------------------------------------------------------+ // Invoked when received GET DEVICE DESCRIPTOR request @@ -132,12 +132,12 @@ uint8_t const * tud_descriptor_bos_cb(void); // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. -TU_ATTR_WEAK uint8_t const* tud_descriptor_device_qualifier_cb(void); +uint8_t const* tud_descriptor_device_qualifier_cb(void); // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa -TU_ATTR_WEAK uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index); +uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index); // Invoked when device is mounted (configured) void tud_mount_cb(void); -- cgit v1.3.1 From 8183433600a675a54964d0a36efb814f77f38a54 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jul 2024 21:05:10 +0700 Subject: fix compile with tud_vendor_control_xfer_cb() and check tud_descriptor_device_cb() --- src/device/usbd.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index f0d7c45b1..b93216006 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -708,8 +708,6 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // Vendor request if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR ) { - TU_VERIFY(tud_vendor_control_xfer_cb); - usbd_control_set_complete_callback(tud_vendor_control_xfer_cb); return tud_vendor_control_xfer_cb(rhport, CONTROL_STAGE_SETUP, p_request); } @@ -1060,25 +1058,23 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const switch(desc_type) { - case TUSB_DESC_DEVICE: - { + case TUSB_DESC_DEVICE: { TU_LOG_USBD(" Device\r\n"); void* desc_device = (void*) (uintptr_t) tud_descriptor_device_cb(); + TU_ASSERT(desc_device); // Only response with exactly 1 Packet if: not addressed and host requested more data than device descriptor has. // This only happens with the very first get device descriptor and EP0 size = 8 or 16. if ((CFG_TUD_ENDPOINT0_SIZE < sizeof(tusb_desc_device_t)) && !_usbd_dev.addressed && - ((tusb_control_request_t const*) p_request)->wLength > sizeof(tusb_desc_device_t)) - { + ((tusb_control_request_t const*) p_request)->wLength > sizeof(tusb_desc_device_t)) { // Hack here: we modify the request length to prevent usbd_control response with zlp // since we are responding with 1 packet & less data than wLength. tusb_control_request_t mod_request = *p_request; mod_request.wLength = CFG_TUD_ENDPOINT0_SIZE; return tud_control_xfer(rhport, &mod_request, desc_device, CFG_TUD_ENDPOINT0_SIZE); - }else - { + }else { return tud_control_xfer(rhport, p_request, desc_device, sizeof(tusb_desc_device_t)); } } -- cgit v1.3.1 From 6bb59eeb3f974f51fbc5c6a5e4c02f83e11567b8 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jul 2024 22:33:53 +0700 Subject: add lpc11u37 for hil rpi --- .idea/cmake.xml | 3 ++- hw/bsp/lpc11/family.c | 7 +++++++ hw/bsp/lpc11/family.cmake | 1 + test/hil/rpi.json | 7 +++++++ tools/get_deps.py | 2 +- 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index f09e185b1..67e793016 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -69,7 +69,7 @@ - + @@ -117,6 +117,7 @@ + diff --git a/hw/bsp/lpc11/family.c b/hw/bsp/lpc11/family.c index bff7110b8..e75bc4919 100644 --- a/hw/bsp/lpc11/family.c +++ b/hw/bsp/lpc11/family.c @@ -90,6 +90,13 @@ void board_led_write(bool state) { Chip_GPIO_SetPinState(LPC_GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + if ( max_len < 16 ) return 0; + uint32_t* id32 = (uint32_t*) (uintptr_t) id; + id32[0] = Chip_IAP_ReadUID(); + return 4; +} + uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == Chip_GPIO_GetPinState(LPC_GPIO, BUTTON_PORT, BUTTON_PIN); } diff --git a/hw/bsp/lpc11/family.cmake b/hw/bsp/lpc11/family.cmake index f17a48dd7..818600656 100644 --- a/hw/bsp/lpc11/family.cmake +++ b/hw/bsp/lpc11/family.cmake @@ -30,6 +30,7 @@ function(add_board_target BOARD_TARGET) ${SDK_DIR}/../gcc/cr_startup_lpc${LPC_FAMILY}.c ${SDK_DIR}/src/chip_${LPC_FAMILY}.c ${SDK_DIR}/src/clock_${LPC_FAMILY}.c + ${SDK_DIR}/src/iap.c ${SDK_DIR}/src/iocon_${LPC_FAMILY}.c ${SDK_DIR}/src/sysinit_${LPC_FAMILY}.c ) diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 98d576db8..bd20b3313 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -46,6 +46,13 @@ "flasher": "jlink", "flasher_sn": "000831174392", "flasher_args": "-device R7FA4M1AB" + }, + { + "name": "lpcxpresso11u37", + "uid": "17121919", + "flasher": "jlink", + "flasher_sn": "000724441579", + "flasher_args": "-device LPC11U37/401" } ] } diff --git a/tools/get_deps.py b/tools/get_deps.py index 555e2d707..7fbde0e02 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -49,7 +49,7 @@ deps_optional = { '2204191ec76283371419fbcec207da02e1bc22fa', 'nuc'], 'hw/mcu/nxp/lpcopen': ['https://github.com/hathach/nxp_lpcopen.git', - '04bfe7a5f6ee74a89a28ad618d3367dcfcfb7d83', + 'b41cf930e65c734d8ec6de04f1d57d46787c76ae', 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43'], 'hw/mcu/nxp/mcux-sdk': ['https://github.com/hathach/mcux-sdk.git', '144f1eb7ea8c06512e12f12b27383601c0272410', -- cgit v1.3.1 From 66193cba05dc9205254dcb839bbea3a53fd03eee Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jul 2024 22:48:01 +0700 Subject: fix build with make --- hw/bsp/lpc11/family.mk | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hw/bsp/lpc11/family.mk b/hw/bsp/lpc11/family.mk index 09713fd55..a3ec33768 100644 --- a/hw/bsp/lpc11/family.mk +++ b/hw/bsp/lpc11/family.mk @@ -9,13 +9,18 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_LPC11UXX \ -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +# mcu driver cause following warnings +CFLAGS += \ + -Wno-error=incompatible-pointer-types \ + +LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c \ $(MCU_DIR)/../gcc/cr_startup_lpc$(MCU_DRV).c \ $(MCU_DIR)/src/chip_$(MCU_DRV).c \ $(MCU_DIR)/src/clock_$(MCU_DRV).c \ + $(MCU_DIR)/src/iap.c \ $(MCU_DIR)/src/iocon_$(MCU_DRV).c \ $(MCU_DIR)/src/sysinit_$(MCU_DRV).c -- cgit v1.3.1 From 4de46fcf975d57983192874feea9d94427f5de50 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Jul 2024 16:01:39 +0700 Subject: fix a bug in fsdev introduced by #1942 --- hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake | 1 - hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake | 1 - hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake | 1 - hw/bsp/ch32v20x/family.cmake | 6 ++++++ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 2 +- 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake index adb0ea741..4aae6bdc2 100644 --- a/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake +++ b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake @@ -10,7 +10,6 @@ set(LD_RAM_SIZE 20K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC SYSCLK_FREQ_144MHz_HSE=144000000 - CH32_FLASH_ENHANCE_READ_MODE=1 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() diff --git a/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake index 6fe3e05b2..ecb8b378f 100644 --- a/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake +++ b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake @@ -8,7 +8,6 @@ set(LD_RAM_SIZE 10K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC SYSCLK_FREQ_144MHz_HSI=144000000 - CH32_FLASH_ENHANCE_READ_MODE=1 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake index ed7365797..a0bf12b5c 100644 --- a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake @@ -8,7 +8,6 @@ set(LD_RAM_SIZE 20K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC SYSCLK_FREQ_144MHz_HSE=144000000 - CH32_FLASH_ENHANCE_READ_MODE=1 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake index bf929b862..380ef190d 100644 --- a/hw/bsp/ch32v20x/family.cmake +++ b/hw/bsp/ch32v20x/family.cmake @@ -72,6 +72,12 @@ function(add_board_target BOARD_TARGET) update_board(${BOARD_TARGET}) + if (LD_FLASH_SIZE STREQUAL 224K) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CH32_FLASH_ENHANCE_READ_MODE=1 + ) + endif() + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(${BOARD_TARGET} PUBLIC -mcmodel=medany diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 8bfb899ca..39f33bc34 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -1004,7 +1004,7 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui srcVal++; } - if (wNBytes) { + if (wNBytes & 0x01) { temp1 = (uint16_t) *srcVal; *pdwVal = temp1; } -- cgit v1.3.1 From ce5fe3cc196df343c96477045868c60ac34516cf Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Jul 2024 22:05:21 +0700 Subject: change s3 baudrate --- test/hil/rpi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hil/rpi.json b/test/hil/rpi.json index bd20b3313..dae3094b5 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -29,7 +29,7 @@ ], "flasher": "esptool", "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", - "flasher_args": "-b 1500000" + "flasher_args": "-b 921600" }, { "name": "metro_m7_1011", -- cgit v1.3.1 From 5d26f5794e991409addfd9501ee04ad4e68dd1af Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Jul 2024 18:05:44 +0700 Subject: update fsdev bsp for hil testing --- hw/bsp/stm32f3/family.c | 13 +++++++++++++ hw/bsp/stm32g4/FreeRTOSConfig/FreeRTOSConfig.h | 2 +- hw/bsp/stm32l0/family.c | 13 +++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/hw/bsp/stm32f3/family.c b/hw/bsp/stm32f3/family.c index e7488ba84..f94dd95cf 100644 --- a/hw/bsp/stm32f3/family.c +++ b/hw/bsp/stm32f3/family.c @@ -116,6 +116,19 @@ uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; + uint32_t* id32 = (uint32_t*) (uintptr_t) id; + uint8_t const len = 12; + + id32[0] = stm32_uuid[0]; + id32[1] = stm32_uuid[1]; + id32[2] = stm32_uuid[2]; + + return len; +} + int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; diff --git a/hw/bsp/stm32g4/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32g4/FreeRTOSConfig/FreeRTOSConfig.h index fa3f0ac33..891ea4b79 100644 --- a/hw/bsp/stm32g4/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/stm32g4/FreeRTOSConfig/FreeRTOSConfig.h @@ -58,7 +58,7 @@ #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) -#define configMINIMAL_STACK_SIZE ( 128 ) +#define configMINIMAL_STACK_SIZE ( 200 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 diff --git a/hw/bsp/stm32l0/family.c b/hw/bsp/stm32l0/family.c index ea7f0b73d..c8c88d687 100644 --- a/hw/bsp/stm32l0/family.c +++ b/hw/bsp/stm32l0/family.c @@ -126,6 +126,19 @@ uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; + uint32_t* id32 = (uint32_t*) (uintptr_t) id; + uint8_t const len = 12; + + id32[0] = stm32_uuid[0]; + id32[1] = stm32_uuid[1]; + id32[2] = stm32_uuid[2]; + + return len; +} + int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; -- cgit v1.3.1 From c0f38ebf8d483da02a9074eaf021e1660a55fd75 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Jul 2024 19:53:41 +0700 Subject: fsdev read/write packet use unaligned function --- hw/bsp/ch32v20x/family.c | 11 +++ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 108 +++++++++++--------------- src/portable/st/stm32_fsdev/fsdev_common.h | 13 +++- 3 files changed, 64 insertions(+), 68 deletions(-) diff --git a/hw/bsp/ch32v20x/family.c b/hw/bsp/ch32v20x/family.c index 542d4b5db..43dd7e032 100644 --- a/hw/bsp/ch32v20x/family.c +++ b/hw/bsp/ch32v20x/family.c @@ -173,6 +173,17 @@ uint32_t board_button_read(void) { return false; } +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + volatile uint32_t* ch32_uuid = ((volatile uint32_t*) 0x1FFFF7E8UL); + uint32_t* serial_32 = (uint32_t*) (uintptr_t) id; + serial_32[0] = ch32_uuid[0]; + serial_32[1] = ch32_uuid[1]; + serial_32[2] = ch32_uuid[2]; + + return 12; +} + int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 39f33bc34..8c2b10691 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -426,6 +426,8 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) dcd_read_packet_memory(userMemBuf, pcd_get_ep_rx_address(USB, EPindex), 8); dcd_event_setup_received(0, (uint8_t *)userMemBuf, true); #endif + } else { + TU_BREAKPOINT(); } } else { // Clear RX CTR interrupt flag @@ -941,27 +943,26 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) } #ifdef FSDEV_BUS_32BIT -static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) -{ - const uint8_t *srcVal = src; +static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) { + const uint8_t *src8 = src; volatile uint32_t *dst32 = (volatile uint32_t *)(USB_PMAADDR + dst); for (uint32_t n = wNBytes / 4; n > 0; --n) { - *dst32++ = tu_unaligned_read32(srcVal); - srcVal += 4; + *dst32++ = tu_unaligned_read32(src8); + src8 += 4; } - wNBytes = wNBytes & 0x03; - if (wNBytes) { - uint32_t wrVal = *srcVal; - wNBytes--; + uint16_t odd = wNBytes & 0x03; + if (odd) { + uint32_t wrVal = *src8; + odd--; - if (wNBytes) { - wrVal |= *++srcVal << 8; - wNBytes--; + if (odd) { + wrVal |= *++src8 << 8; + odd--; - if (wNBytes) { - wrVal |= *++srcVal << 16; + if (odd) { + wrVal |= *++src8 << 16; } } @@ -974,39 +975,26 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui // Packet buffer access can only be 8- or 16-bit. /** * @brief Copy a buffer from user memory area to packet memory area (PMA). - * This uses byte-access for user memory (so support non-aligned buffers) - * and 16-bit access for packet memory. + * This uses un-aligned for user memory and 16-bit access for packet memory. * @param dst, byte address in PMA; must be 16-bit aligned * @param src pointer to user memory area. * @param wPMABufAddr address into PMA. * @param wNBytes no. of bytes to be copied. * @retval None */ -static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) -{ +static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) { uint32_t n = (uint32_t)wNBytes >> 1U; - uint16_t temp1, temp2; - const uint8_t *srcVal; - - // The GCC optimizer will combine access to 32-bit sizes if we let it. Force - // it volatile so that it won't do that. - __IO uint16_t *pdwVal; - - srcVal = src; - pdwVal = &pma[FSDEV_PMA_STRIDE * (dst >> 1)]; + const uint8_t *src8 = src; + volatile uint16_t *pdw16 = &pma[FSDEV_PMA_STRIDE * (dst >> 1)]; while (n--) { - temp1 = (uint16_t)*srcVal; - srcVal++; - temp2 = temp1 | ((uint16_t)(((uint16_t)(*srcVal)) << 8U)); - *pdwVal = temp2; - pdwVal += FSDEV_PMA_STRIDE; - srcVal++; + *pdw16 = tu_unaligned_read16(src8); + src8 += 2; + pdw16 += FSDEV_PMA_STRIDE; } if (wNBytes & 0x01) { - temp1 = (uint16_t) *srcVal; - *pdwVal = temp1; + *pdw16 = (uint16_t) *src8; } return true; @@ -1091,27 +1079,27 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNB #ifdef FSDEV_BUS_32BIT static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { - uint8_t *dstVal = dst; + uint8_t *dst8 = dst; volatile uint32_t *src32 = (volatile uint32_t *)(USB_PMAADDR + src); for (uint32_t n = wNBytes / 4; n > 0; --n) { - tu_unaligned_write32(dstVal, *src32++); - dstVal += 4; + tu_unaligned_write32(dst8, *src32++); + dst8 += 4; } - wNBytes = wNBytes & 0x03; - if (wNBytes) { + uint16_t odd = wNBytes & 0x03; + if (odd) { uint32_t rdVal = *src32; - *dstVal = tu_u32_byte0(rdVal); - wNBytes--; + *dst8 = tu_u32_byte0(rdVal); + odd--; - if (wNBytes) { - *++dstVal = tu_u32_byte1(rdVal); - wNBytes--; + if (odd) { + *++dst8 = tu_u32_byte1(rdVal); + odd--; - if (wNBytes) { - *++dstVal = tu_u32_byte2(rdVal); + if (odd) { + *++dst8 = tu_u32_byte2(rdVal); } } } @@ -1121,33 +1109,25 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t #else /** * @brief Copy a buffer from packet memory area (PMA) to user memory area. - * Uses byte-access of system memory and 16-bit access of packet memory + * Uses unaligned for system memory and 16-bit access of packet memory * @param wNBytes no. of bytes to be copied. * @retval None */ -static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) -{ +static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { uint32_t n = (uint32_t)wNBytes >> 1U; - // The GCC optimizer will combine access to 32-bit sizes if we let it. Force - // it volatile so that it won't do that. - __IO const uint16_t *pdwVal; - uint32_t temp; - - pdwVal = &pma[FSDEV_PMA_STRIDE * (src >> 1)]; - uint8_t *dstVal = (uint8_t *)dst; + volatile const uint16_t *pdw16 = &pma[FSDEV_PMA_STRIDE * (src >> 1)]; + uint8_t *dst8 = (uint8_t *)dst; while (n--) { - temp = *pdwVal; - pdwVal += FSDEV_PMA_STRIDE; - *dstVal++ = ((temp >> 0) & 0xFF); - *dstVal++ = ((temp >> 8) & 0xFF); + tu_unaligned_write16(dst8, *pdw16); + dst8 += 2; + pdw16 += FSDEV_PMA_STRIDE; } if (wNBytes & 0x01) { - temp = *pdwVal; - pdwVal += FSDEV_PMA_STRIDE; - *dstVal++ = ((temp >> 0) & 0xFF); + *dst8++ = tu_u16_low(*pdw16); } + return true; } #endif diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index e8a6af8cb..920c17a04 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -35,14 +35,19 @@ #include "stdint.h" // FSDEV_PMA_SIZE is PMA buffer size in bytes. -// On 512-byte devices, access with a stride of two words (use every other 16-bit address) -// On 1024-byte devices, access with a stride of one word (use every 16-bit address) +// - 512-byte devices, access with a stride of two words (use every other 16-bit address) +// - 1024-byte devices, access with a stride of one word (use every 16-bit address) +// - 2048-byte devices, access with 32-bit address // For purposes of accessing the packet -#if ((FSDEV_PMA_SIZE) == 512u) +#if FSDEV_PMA_SIZE == 512 #define FSDEV_PMA_STRIDE (2u) -#elif ((FSDEV_PMA_SIZE) == 1024u) +#elif FSDEV_PMA_SIZE == 1024 #define FSDEV_PMA_STRIDE (1u) +#elif FSDEV_PMA_SIZE == 2048 + #ifndef FSDEV_BUS_32BIT + #warning "FSDEV_PMA_SIZE is 2048, but FSDEV_BUS_32BIT is not defined" + #endif #endif // The fsdev_bus_t type can be used for both register and PMA access necessities -- cgit v1.3.1 From 2f8078f5b57568f32e0d4d87c95fb32e00389b3d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Jul 2024 16:59:12 +0700 Subject: minor changes --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 111 ++++++++++---------------- 1 file changed, 43 insertions(+), 68 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 8c2b10691..8eb463351 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -180,7 +180,7 @@ static uint8_t remoteWakeCountdown; // When wake is requested //--------------------------------------------------------------------+ // into the stack. -static void dcd_handle_bus_reset(void); +static void handle_bus_reset(uint8_t rhport); static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix); static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr); static void dcd_ep_ctr_handler(void); @@ -212,18 +212,12 @@ TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint32_t ep_addr) //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ - -void dcd_init(uint8_t rhport) -{ - /* Clocks should already be enabled */ - /* Use __HAL_RCC_USB_CLK_ENABLE(); to enable the clocks before calling this function */ - - /* The RM mentions to use a special ordering of PDWN and FRES, but this isn't done in HAL. - * Here, the RM is followed. */ - +void dcd_init(uint8_t rhport) { + // Follow the RM mentions to use a special ordering of PDWN and FRES for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } + // Perform USB peripheral reset USB->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us @@ -238,9 +232,11 @@ void dcd_init(uint8_t rhport) } USB->CNTR = 0; // Enable USB -#if !defined(STM32G0) && !defined(STM32H5) && !defined(STM32U5) // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address +#if !defined(STM32G0) && !defined(STM32H5) && !defined(STM32U5) + // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address USB->BTABLE = DCD_STM32_BTABLE_BASE; #endif + USB->ISTR = 0; // Clear pending interrupts // Reset endpoints to disabled @@ -250,17 +246,14 @@ void dcd_init(uint8_t rhport) } USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; - dcd_handle_bus_reset(); + handle_bus_reset(rhport); // Enable pull-up if supported dcd_connect(rhport); } - -void dcd_sof_enable(uint8_t rhport, bool en) -{ +void dcd_sof_enable(uint8_t rhport, bool en) { (void)rhport; - (void)en; if (en) { USB->CNTR |= USB_CNTR_SOFM; @@ -270,9 +263,7 @@ void dcd_sof_enable(uint8_t rhport, bool en) } // Receive Set Address request, mcu port must also include status IN response -void dcd_set_address(uint8_t rhport, uint8_t dev_addr) -{ - (void)rhport; +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void)dev_addr; // Respond with status @@ -282,35 +273,15 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) // do it at dcd_edpt0_status_complete() } -void dcd_remote_wakeup(uint8_t rhport) -{ +void dcd_remote_wakeup(uint8_t rhport) { (void)rhport; USB->CNTR |= USB_CNTR_RESUME; remoteWakeCountdown = 4u; // required to be 1 to 15 ms, ESOF should trigger every 1ms. } -static const tusb_desc_endpoint_t ep0OUT_desc = { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = 0x00, - .bmAttributes = {.xfer = TUSB_XFER_CONTROL}, - .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, - .bInterval = 0 -}; - -static const tusb_desc_endpoint_t ep0IN_desc = { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = 0x80, - .bmAttributes = {.xfer = TUSB_XFER_CONTROL}, - .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, - .bInterval = 0 -}; - -static void dcd_handle_bus_reset(void) -{ - USB->DADDR = 0u; // disable USB peripheral by clearing the EF flag +static void handle_bus_reset(uint8_t rhport) { + USB->DADDR = 0u; // disable USB Function for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) { // Clear EP allocation status @@ -323,17 +294,26 @@ static void dcd_handle_bus_reset(void) // Reset PMA allocation ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX; - dcd_edpt_open(0, &ep0OUT_desc); - dcd_edpt_open(0, &ep0IN_desc); + tusb_desc_endpoint_t ep0_desc = { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + .bEndpointAddress = 0x00, + .bmAttributes = {.xfer = TUSB_XFER_CONTROL}, + .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, + .bInterval = 0 + }; + + dcd_edpt_open(rhport, &ep0_desc); + + ep0_desc.bEndpointAddress = 0x80; + dcd_edpt_open(rhport, &ep0_desc); - USB->DADDR = USB_DADDR_EF; // Set enable flag, and leaving the device address as zero. + USB->DADDR = USB_DADDR_EF; // Enable USB Function } // Handle CTR interrupt for the TX/IN direction -// // Upon call, (wIstr & USB_ISTR_DIR) == 0U -static void dcd_ep_ctr_tx_handler(uint32_t wIstr) -{ +static void dcd_ep_ctr_tx_handler(uint32_t wIstr) { uint32_t EPindex = wIstr & USB_ISTR_EP_ID; uint32_t wEPRegVal = pcd_get_endpoint(USB, EPindex); uint8_t ep_addr = (wEPRegVal & USB_EPADDR_FIELD) | TUSB_DIR_IN_MASK; @@ -406,6 +386,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) // Verify the CTR_RX bit is set. This was in the ST Micro code, // but I'm not sure it's actually necessary? if ((wEPRegVal & USB_EP_CTR_RX) == 0U) { + // TU_ASSERT(false, ); return; } @@ -504,10 +485,7 @@ static void dcd_ep_ctr_handler(void) } } -void dcd_int_handler(uint8_t rhport) -{ - (void)rhport; - +void dcd_int_handler(uint8_t rhport) { uint32_t int_status = USB->ISTR; // const uint32_t handled_ints = USB_ISTR_CTR | USB_ISTR_RESET | USB_ISTR_WKUP // | USB_ISTR_SUSP | USB_ISTR_SOF | USB_ISTR_ESOF; @@ -526,7 +504,7 @@ void dcd_int_handler(uint8_t rhport) if (int_status & USB_ISTR_RESET) { // USBRST is start of reset. USB->ISTR = (fsdev_bus_t)~USB_ISTR_RESET; - dcd_handle_bus_reset(); + handle_bus_reset(rhport); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); return; // Don't do the rest of the things here; perhaps they've been cleared? } @@ -659,13 +637,12 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) // The STM32F0 doesn't seem to like |= or &= to manipulate the EP#R registers, // so I'm using the #define from HAL here, instead. -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) -{ +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void)rhport; - uint8_t const ep_addr = p_endpoint_desc->bEndpointAddress; - uint8_t const ep_idx = dcd_ep_alloc(ep_addr, p_endpoint_desc->bmAttributes.xfer); + uint8_t const ep_addr = desc_ep->bEndpointAddress; + uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); uint8_t const dir = tu_edpt_dir(ep_addr); - const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc); + const uint16_t packet_size = tu_edpt_packet_size(desc_ep); const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size); uint16_t pma_addr; uint32_t wType; @@ -674,7 +651,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) TU_ASSERT(buffer_size <= 64); // Set type - switch (p_endpoint_desc->bmAttributes.xfer) { + switch (desc_ep->bmAttributes.xfer) { case TUSB_XFER_CONTROL: wType = USB_EP_CONTROL; break; @@ -807,7 +784,6 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoin } // Currently, single-buffered, and only 64 bytes at a time (max) - static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = (uint16_t)(xfer->total_len - xfer->queued_len); @@ -1007,8 +983,7 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui * @param wNBytes no. of bytes to be copied. * @retval None */ -static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes) -{ +static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes) { // Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies tu_fifo_buffer_info_t info; tu_fifo_get_read_info(ff, &info); @@ -1042,8 +1017,9 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNB dst += 4; // Copy rest of wrapped byte - if (wCnt) + if (wCnt) { dcd_write_packet_memory(dst, info.ptr_wrap, wCnt); + } } #else if ((cnt_lin & 0x01) && cnt_wrap) { @@ -1077,8 +1053,7 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNB } #ifdef FSDEV_BUS_32BIT -static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) -{ +static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { uint8_t *dst8 = dst; volatile uint32_t *src32 = (volatile uint32_t *)(USB_PMAADDR + src); @@ -1138,8 +1113,7 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t * @param wNBytes no. of bytes to be copied. * @retval None */ -static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes) -{ +static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes) { // Since we copy into a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies // Check for first linear part tu_fifo_buffer_info_t info; @@ -1173,8 +1147,9 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBy } // Copy rest of wrapped byte - if (wCnt) + if (wCnt) { dcd_read_packet_memory(info.ptr_wrap, src, wCnt); + } } #else if ((cnt_lin & 0x01) && cnt_wrap) { -- cgit v1.3.1 From 0eb0baed190ea671b74528942e4fda87acd259a8 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Jul 2024 11:53:42 +0700 Subject: fsdev: remove unused _setup_packet --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 38 +++++++++++---------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 8eb463351..602b220ab 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -168,11 +168,8 @@ typedef struct { } ep_alloc_t; static xfer_ctl_t xfer_status[CFG_TUD_ENDPPOINT_MAX][2]; - static ep_alloc_t ep_alloc_status[FSDEV_EP_COUNT]; -static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6]; - static uint8_t remoteWakeCountdown; // When wake is requested //--------------------------------------------------------------------+ @@ -386,18 +383,28 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) // Verify the CTR_RX bit is set. This was in the ST Micro code, // but I'm not sure it's actually necessary? if ((wEPRegVal & USB_EP_CTR_RX) == 0U) { - // TU_ASSERT(false, ); return; } - if ((ep_addr == 0U) && ((wEPRegVal & USB_EP_SETUP) != 0U)) { + if (wEPRegVal & USB_EP_SETUP) { /* Setup packet */ uint32_t count = pcd_get_ep_rx_cnt(USB, EPindex); // Setup packet should always be 8 bytes. If not, ignore it, and try again. if (count == 8) { - // Must reset EP to NAK (in case it had been stalling) (though, maybe too late here) + // Must reset EP to NAK (in case it had been stalling) pcd_set_ep_rx_status(USB, 0u, USB_EP_RX_NAK); pcd_set_ep_tx_status(USB, 0u, USB_EP_TX_NAK); + + // set both data toggle to 1 + uint32_t regVal = pcd_get_endpoint(USB, 0); + if ((regVal & USB_EP_DTOG_TX) == 0) { + pcd_tx_dtog(USB, 0); + } + + if ((regVal & USB_EP_DTOG_RX) == 0) { + pcd_rx_dtog(USB, 0); + } + #ifdef FSDEV_BUS_32BIT dcd_event_setup_received(0, (uint8_t *)(USB_PMAADDR + pcd_get_ep_rx_address(USB, EPindex)), true); #else @@ -405,17 +412,14 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) // user memory, to allow for the 32-bit access that memcpy performs. uint8_t userMemBuf[8]; dcd_read_packet_memory(userMemBuf, pcd_get_ep_rx_address(USB, EPindex), 8); - dcd_event_setup_received(0, (uint8_t *)userMemBuf, true); + dcd_event_setup_received(0, (uint8_t*) userMemBuf, true); #endif - } else { - TU_BREAKPOINT(); } } else { // Clear RX CTR interrupt flag if (ep_addr != 0u) { pcd_clear_rx_ep_ctr(USB, EPindex); } - uint32_t count; uint16_t addr; /* Read from correct register when ISOCHRONOUS (double buffered) */ @@ -553,18 +557,14 @@ void dcd_int_handler(uint8_t rhport) { // Invoked when a control transfer's status stage is complete. // May help DCD to prepare for next control transfer, this API is optional. -void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) -{ +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { (void)rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) { uint8_t const dev_addr = (uint8_t)request->wValue; - - // Setting new address after the whole request is complete - USB->DADDR &= ~USB_DADDR_ADD; - USB->DADDR |= dev_addr; // leave the enable bit set + USB->DADDR = (USB_DADDR_EF | dev_addr); } } @@ -834,12 +834,6 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) if (dir == TUSB_DIR_IN) { dcd_transmit_packet(xfer, ep_idx); } else { - // A setup token can occur immediately after an OUT STATUS packet so make sure we have a valid - // buffer for the control endpoint. - if (ep_idx == 0 && xfer->buffer == NULL) { - xfer->buffer = (uint8_t *)_setup_packet; - } - uint32_t cnt = (uint32_t ) tu_min16(xfer->total_len, xfer->max_packet_size); uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx); -- cgit v1.3.1 From a5bc0430f75c4e2088690467b369db7e24bba97b Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Jul 2024 16:49:01 +0700 Subject: fix race condition where reset event cleaar setup count --- src/device/dcd.h | 22 +++++++++------------- src/device/usbd.c | 11 +++++++---- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/device/dcd.h b/src/device/dcd.h index 5356e9be1..b25b47025 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -40,19 +40,15 @@ //--------------------------------------------------------------------+ typedef enum { - DCD_EVENT_INVALID = 0, - DCD_EVENT_BUS_RESET, - DCD_EVENT_UNPLUGGED, - DCD_EVENT_SOF, - DCD_EVENT_SUSPEND, // TODO LPM Sleep L1 support - DCD_EVENT_RESUME, - - DCD_EVENT_SETUP_RECEIVED, - DCD_EVENT_XFER_COMPLETE, - - // Not an DCD event, just a convenient way to defer ISR function - USBD_EVENT_FUNC_CALL, - + DCD_EVENT_INVALID = 0, // 0 + DCD_EVENT_BUS_RESET, // 1 + DCD_EVENT_UNPLUGGED, // 2 + DCD_EVENT_SOF, // 3 + DCD_EVENT_SUSPEND, // 4 TODO LPM Sleep L1 support + DCD_EVENT_RESUME, // 5 + DCD_EVENT_SETUP_RECEIVED, // 6 + DCD_EVENT_XFER_COMPLETE, // 7 + USBD_EVENT_FUNC_CALL, // 8 Not an DCD event, just a convenient way to defer ISR function DCD_EVENT_COUNT } dcd_eventid_t; diff --git a/src/device/usbd.c b/src/device/usbd.c index b93216006..d9b20d26d 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -120,7 +120,6 @@ typedef struct { }; volatile uint8_t cfg_num; // current active configuration (0x00 is not configured) uint8_t speed; - volatile uint8_t setup_count; volatile uint8_t sof_consumer; uint8_t itf2drv[CFG_TUD_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) @@ -131,6 +130,7 @@ typedef struct { }usbd_device_t; tu_static usbd_device_t _usbd_dev; +static volatile uint8_t _usbd_queued_setup; //--------------------------------------------------------------------+ // Class Driver @@ -459,6 +459,7 @@ bool tud_init(uint8_t rhport) { TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_edpt_stream_t)); tu_varclr(&_usbd_dev); + _usbd_queued_setup = 0; #if OSAL_MUTEX_REQUIRED // Init device mutex @@ -594,9 +595,10 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { break; case DCD_EVENT_SETUP_RECEIVED: - _usbd_dev.setup_count--; + TU_ASSERT(_usbd_queued_setup > 0,); + _usbd_queued_setup--; TU_LOG_BUF(CFG_TUD_LOG_LEVEL, &event.setup_received, 8); - if (_usbd_dev.setup_count) { + if (_usbd_queued_setup) { TU_LOG_USBD(" Skipped since there is other SETUP in queue\r\n"); break; } @@ -1199,7 +1201,8 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) break; case DCD_EVENT_SETUP_RECEIVED: - _usbd_dev.setup_count++; + // TU_ASSERT(event->setup_received.bRequest != 0,); + _usbd_queued_setup++; send = true; break; -- cgit v1.3.1 From 02caf007723551f878ab3675c14681801f16354e Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Jul 2024 19:00:59 +0700 Subject: simplify btable rx/tx count/address access --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 20 +--- src/portable/st/stm32_fsdev/fsdev_common.h | 136 ++++++++++++++++++-------- 2 files changed, 98 insertions(+), 58 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 602b220ab..927ecac85 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -129,21 +129,7 @@ // Configuration //--------------------------------------------------------------------+ -// hardware limit endpoint -#define FSDEV_EP_COUNT 8 -// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it -// Both of these MUST be a multiple of 2, and are in byte units. -#ifndef DCD_STM32_BTABLE_BASE -#define DCD_STM32_BTABLE_BASE 0U -#endif - -#ifndef DCD_STM32_BTABLE_SIZE -#define DCD_STM32_BTABLE_SIZE (FSDEV_PMA_SIZE - DCD_STM32_BTABLE_BASE) -#endif - -TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_SIZE)) <= (FSDEV_PMA_SIZE), "BTABLE does not fit in PMA RAM"); -TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligned to 8 bytes"); //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF @@ -231,7 +217,7 @@ void dcd_init(uint8_t rhport) { #if !defined(STM32G0) && !defined(STM32H5) && !defined(STM32U5) // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address - USB->BTABLE = DCD_STM32_BTABLE_BASE; + USB->BTABLE = FSDEV_BTABLE_BASE; #endif USB->ISTR = 0; // Clear pending interrupts @@ -289,7 +275,7 @@ static void handle_bus_reset(uint8_t rhport) { } // Reset PMA allocation - ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX; + ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT; tusb_desc_endpoint_t ep0_desc = { .bLength = sizeof(tusb_desc_endpoint_t), @@ -705,7 +691,7 @@ void dcd_edpt_close_all(uint8_t rhport) } // Reset PMA allocation - ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE; + ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE; } /** diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 920c17a04..d0f928552 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -34,6 +34,14 @@ #include "stdint.h" +// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it +// Both of these MUST be a multiple of 2, and are in byte units. +#ifndef FSDEV_BTABLE_BASE +#define FSDEV_BTABLE_BASE 0U +#endif + +TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 bytes"); + // FSDEV_PMA_SIZE is PMA buffer size in bytes. // - 512-byte devices, access with a stride of two words (use every other 16-bit address) // - 1024-byte devices, access with a stride of one word (use every 16-bit address) @@ -41,15 +49,50 @@ // For purposes of accessing the packet #if FSDEV_PMA_SIZE == 512 - #define FSDEV_PMA_STRIDE (2u) + #define FSDEV_PMA_STRIDE (2u) // 1x16 bit access scheme + #define pma_aligned TU_ATTR_ALIGNED(4) #elif FSDEV_PMA_SIZE == 1024 - #define FSDEV_PMA_STRIDE (1u) + #define FSDEV_PMA_STRIDE (1u) // 2x16 bit access scheme + #define pma_aligned #elif FSDEV_PMA_SIZE == 2048 #ifndef FSDEV_BUS_32BIT #warning "FSDEV_PMA_SIZE is 2048, but FSDEV_BUS_32BIT is not defined" #endif + #define FSDEV_PMA_STRIDE (1u) // 32 bit access scheme + #define pma_aligned #endif +// hardware limit endpoint +#define FSDEV_EP_COUNT 8 + +// Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either +// 16-bit or 32-bit depending on FSDEV_BUS_32BIT. +typedef struct { + union { + struct { + volatile pma_aligned uint16_t tx_addr; + volatile pma_aligned uint16_t tx_count; + volatile pma_aligned uint16_t rx_addr; + volatile pma_aligned uint16_t rx_count; + } ep16[FSDEV_EP_COUNT]; + + struct { + volatile uint32_t tx_count_addr; + volatile uint32_t rx_count_addr; + } ep32[FSDEV_EP_COUNT]; + }; +} fsdev_btable_t; + +TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT*8*FSDEV_PMA_STRIDE, "size is not correct"); +TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM"); + + +#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) + +//--------------------------------------------------------------------+ +// Helper +//--------------------------------------------------------------------+ + // The fsdev_bus_t type can be used for both register and PMA access necessities // For type-safety create a new macro for the volatile address of PMAADDR // The compiler should warn us if we cast it to a non-volatile type? @@ -110,6 +153,21 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx return *reg; } +/** + * @brief Sets address in an endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpIdx Endpoint Number. + * @param bAddr Address. + * @retval None + */ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPREG_MASK; + regVal |= bAddr; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpIdx,regVal); +} + TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= (uint32_t)USB_EP_T_MASK; @@ -153,58 +211,47 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, * @retval Counter value */ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - return (pma32[2*bEpIdx] & 0x03FF0000) >> 16; + uint16_t count; +#ifdef FSDEV_BUS_32BIT + count = (FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr >> 16); #else - volatile const uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpIdx); - return *regPtr & 0x3ffU; + count = FSDEV_BTABLE->ep16[bEpIdx].tx_count; #endif + + return count & 0x3FFU; } TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - return (pma32[2*bEpIdx + 1] & 0x03FF0000) >> 16; + uint16_t count; +#ifdef FSDEV_BUS_32BIT + count = (FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr >> 16); #else - volatile const uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpIdx); - return *regPtr & 0x3ffU; + count = FSDEV_BTABLE->ep16[bEpIdx].rx_count; #endif + + return count & 0x3FFU; } #define pcd_get_ep_dbuf0_cnt pcd_get_ep_tx_cnt #define pcd_get_ep_dbuf1_cnt pcd_get_ep_rx_cnt -/** - * @brief Sets address in an endpoint register. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @param bAddr Address. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal |= bAddr; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx,regVal); -} - TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - return pma32[2*bEpIdx] & 0x0000FFFFu ; +#ifdef FSDEV_BUS_32BIT + return FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr & 0x0000FFFFu; #else - return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u); + return FSDEV_BTABLE->ep16[bEpIdx].tx_addr; #endif } TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - return pma32[2*bEpIdx + 1] & 0x0000FFFFu; +#ifdef FSDEV_BUS_32BIT + return FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr & 0x0000FFFFu; #else - return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u); + return FSDEV_BTABLE->ep16[bEpIdx].rx_addr; #endif } @@ -212,20 +259,24 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * #define pcd_get_ep_dbuf1_address pcd_get_ep_rx_address TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - pma32[2*bEpIdx] = (pma32[2*bEpIdx] & 0xFFFF0000u) | (addr & 0x0000FFFCu); +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr; + count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); + FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr = count_addr; #else - *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u) = addr; + FSDEV_BTABLE->ep16[bEpIdx].tx_addr = addr; #endif } TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & 0xFFFF0000u) | (addr & 0x0000FFFCu); +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr; + count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); + FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr = count_addr; #else - *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u) = addr; + FSDEV_BTABLE->ep16[bEpIdx].rx_addr = addr; #endif } @@ -233,12 +284,15 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USB #define pcd_set_ep_dbuf1_address pcd_set_ep_rx_address TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - pma32[2*bEpIdx] = (pma32[2*bEpIdx] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr; + count_addr = (count_addr & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); + FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr = count_addr; #else - volatile uint16_t * reg = pcd_ep_tx_cnt_ptr(USBx, bEpIdx); - *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); + uint16_t count = FSDEV_BTABLE->ep16[bEpIdx].tx_count; + count = (count & ~0x3FFU) | (wCount & 0x3FFU); + FSDEV_BTABLE->ep16[bEpIdx].tx_count = count; #endif } -- cgit v1.3.1 From 5122d6d109f8c4b31b6cbe29c685fad30a8961fe Mon Sep 17 00:00:00 2001 From: Brent Kowal Date: Thu, 25 Jul 2024 09:08:37 -0400 Subject: Combined DCD MUSB implementations Combined the new MAX32 MUSB implementation with the existing (TI) implementation to provide generic code base for working the MUSB DCD peripheral. - Added abstraction calls for FIFO setup, EP registers, Ctrl registers and interrupt setup. - Combined TM4C and MSP432E into a single header file. - Created musb_max32.h, and removed the MAX32 specific C implementation. - Updated MAX32 build system to use dcd_musb.c. - Added MAX32 conditions for cdc_dual_ports example descriptors missed during first testing. --- .../device/cdc_dual_ports/src/usb_descriptors.c | 12 + hw/bsp/max32650/family.cmake | 2 +- hw/bsp/max32650/family.mk | 2 +- hw/bsp/max32666/family.cmake | 2 +- hw/bsp/max32666/family.mk | 2 +- hw/bsp/max32690/family.cmake | 2 +- hw/bsp/max32690/family.mk | 2 +- hw/bsp/max78002/family.cmake | 2 +- hw/bsp/max78002/family.mk | 2 +- src/portable/analog/max32/dcd_max32.c | 811 --------------------- src/portable/mentor/musb/dcd_musb.c | 436 ++++------- src/portable/mentor/musb/hcd_musb.c | 12 +- src/portable/mentor/musb/musb_max32.h | 221 ++++++ src/portable/mentor/musb/musb_msp432e.h | 40 - src/portable/mentor/musb/musb_ti.h | 285 ++++++++ src/portable/mentor/musb/musb_tm4c.h | 45 -- src/portable/mentor/musb/musb_type.h | 33 + 17 files changed, 711 insertions(+), 1200 deletions(-) delete mode 100644 src/portable/analog/max32/dcd_max32.c create mode 100644 src/portable/mentor/musb/musb_max32.h delete mode 100644 src/portable/mentor/musb/musb_msp432e.h create mode 100644 src/portable/mentor/musb/musb_ti.h delete mode 100644 src/portable/mentor/musb/musb_tm4c.h diff --git a/examples/device/cdc_dual_ports/src/usb_descriptors.c b/examples/device/cdc_dual_ports/src/usb_descriptors.c index de2505c07..808d78411 100644 --- a/examples/device/cdc_dual_ports/src/usb_descriptors.c +++ b/examples/device/cdc_dual_ports/src/usb_descriptors.c @@ -120,6 +120,18 @@ enum #define EPNUM_CDC_1_OUT 0x05 #define EPNUM_CDC_1_IN 0x86 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_0_NOTIF 0x81 + #define EPNUM_CDC_0_OUT 0x02 + #define EPNUM_CDC_0_IN 0x83 + + #define EPNUM_CDC_1_NOTIF 0x84 + #define EPNUM_CDC_1_OUT 0x05 + #define EPNUM_CDC_1_IN 0x86 + #else #define EPNUM_CDC_0_NOTIF 0x81 #define EPNUM_CDC_0_OUT 0x02 diff --git a/hw/bsp/max32650/family.cmake b/hw/bsp/max32650/family.cmake index 129d99af8..92b68a1cd 100644 --- a/hw/bsp/max32650/family.cmake +++ b/hw/bsp/max32650/family.cmake @@ -132,7 +132,7 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_MAX32650 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC - ${TOP}/src/portable/analog/max32/dcd_max32.c + ${TOP}/src/portable/mentor/musb/dcd_musb.c ) target_compile_options(${TARGET} PRIVATE -Wno-error=strict-prototypes diff --git a/hw/bsp/max32650/family.mk b/hw/bsp/max32650/family.mk index 0718523c3..359261216 100644 --- a/hw/bsp/max32650/family.mk +++ b/hw/bsp/max32650/family.mk @@ -62,7 +62,7 @@ flash: $(DEFAULT_FLASH) # ----------------- PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source SRC_C += \ - src/portable/analog/max32/dcd_max32.c \ + src/portable/mentor/musb/dcd_musb.c \ $(MAX32_CMSIS)/Device/Maxim/MAX32650/Source/heap.c \ $(MAX32_CMSIS)/Device/Maxim/MAX32650/Source/system_max32650.c \ $(MAX32_CMSIS)/Device/Maxim/MAX32650/Source/header_MAX32650.c \ diff --git a/hw/bsp/max32666/family.cmake b/hw/bsp/max32666/family.cmake index ef2a2bb63..eb9d2175f 100644 --- a/hw/bsp/max32666/family.cmake +++ b/hw/bsp/max32666/family.cmake @@ -127,7 +127,7 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_MAX32666 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC - ${TOP}/src/portable/analog/max32/dcd_max32.c + ${TOP}/src/portable/mentor/musb/dcd_musb.c ) target_compile_options(${TARGET} PRIVATE -Wno-error=strict-prototypes diff --git a/hw/bsp/max32666/family.mk b/hw/bsp/max32666/family.mk index 31f81f014..720d994ef 100644 --- a/hw/bsp/max32666/family.mk +++ b/hw/bsp/max32666/family.mk @@ -57,7 +57,7 @@ flash-msdk: $(BUILD)/$(PROJECT).elf # ----------------- PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source SRC_C += \ - src/portable/analog/max32/dcd_max32.c \ + src/portable/mentor/musb/dcd_musb.c \ $(MAX32_CMSIS)/Device/Maxim/MAX32665/Source/heap.c \ $(MAX32_CMSIS)/Device/Maxim/MAX32665/Source/system_max32665.c \ $(PERIPH_SRC)/SYS/mxc_assert.c \ diff --git a/hw/bsp/max32690/family.cmake b/hw/bsp/max32690/family.cmake index d7a562956..2a9422dbe 100644 --- a/hw/bsp/max32690/family.cmake +++ b/hw/bsp/max32690/family.cmake @@ -132,7 +132,7 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_MAX32690 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC - ${TOP}/src/portable/analog/max32/dcd_max32.c + ${TOP}/src/portable/mentor/musb/dcd_musb.c ) target_compile_options(${TARGET} PRIVATE -Wno-error=strict-prototypes diff --git a/hw/bsp/max32690/family.mk b/hw/bsp/max32690/family.mk index 9360a07c6..c533cf4a4 100644 --- a/hw/bsp/max32690/family.mk +++ b/hw/bsp/max32690/family.mk @@ -64,7 +64,7 @@ flash-msdk: $(BUILD)/$(PROJECT).elf # ----------------- PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source SRC_C += \ - src/portable/analog/max32/dcd_max32.c \ + src/portable/mentor/musb/dcd_musb.c \ $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/heap.c \ $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/system_max32690.c \ $(PERIPH_SRC)/SYS/mxc_assert.c \ diff --git a/hw/bsp/max78002/family.cmake b/hw/bsp/max78002/family.cmake index 83fd3007f..090f1da43 100644 --- a/hw/bsp/max78002/family.cmake +++ b/hw/bsp/max78002/family.cmake @@ -137,7 +137,7 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_MAX78002 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC - ${TOP}/src/portable/analog/max32/dcd_max32.c + ${TOP}/src/portable/mentor/musb/dcd_musb.c ) target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) target_compile_options(${TARGET}-tinyusb PRIVATE diff --git a/hw/bsp/max78002/family.mk b/hw/bsp/max78002/family.mk index 8df8517da..5297815de 100644 --- a/hw/bsp/max78002/family.mk +++ b/hw/bsp/max78002/family.mk @@ -60,7 +60,7 @@ flash-msdk: $(BUILD)/$(PROJECT).elf # ----------------- PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source SRC_C += \ - src/portable/analog/max32/dcd_max32.c \ + src/portable/mentor/musb/dcd_musb.c \ $(MAX32_CMSIS)/Device/Maxim/MAX78002/Source/heap.c \ $(MAX32_CMSIS)/Device/Maxim/MAX78002/Source/system_max78002.c \ $(PERIPH_SRC)/SYS/mxc_assert.c \ diff --git a/src/portable/analog/max32/dcd_max32.c b/src/portable/analog/max32/dcd_max32.c deleted file mode 100644 index df616120a..000000000 --- a/src/portable/analog/max32/dcd_max32.c +++ /dev/null @@ -1,811 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2021 Koji KITAYAMA - * Copyright (c) 2024 Brent Kowal (Analog Devices, Inc) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "tusb_option.h" - -#if CFG_TUD_ENABLED && \ - TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002) - - #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) -/* GCC warns that an address may be unaligned, even though - * the target CPU has the capability for unaligned memory access. */ -_Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); - #endif - - #include "device/dcd.h" - - #include "mxc_delay.h" - #include "mxc_device.h" - #include "mxc_sys.h" - #include "nvic_table.h" - #include "usbhs_regs.h" - - #define USBHS_M31_CLOCK_RECOVERY - - /*------------------------------------------------------------------ - * MACRO TYPEDEF CONSTANT ENUM DECLARATION - *------------------------------------------------------------------*/ - #define REQUEST_TYPE_INVALID (0xFFu) - - -typedef union { - uint8_t u8; - uint16_t u16; - uint32_t u32; -} hw_fifo_t; - -typedef struct TU_ATTR_PACKED { - void *buf; /* the start address of a transfer data buffer */ - uint16_t length; /* the number of bytes in the buffer */ - uint16_t remaining; /* the number of bytes remaining in the buffer */ -} pipe_state_t; - -typedef struct -{ - tusb_control_request_t setup_packet; - uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ - int8_t status_out; - pipe_state_t pipe0; - pipe_state_t pipe[2][TUP_DCD_ENDPOINT_MAX - 1]; /* pipe[direction][endpoint number - 1] */ - uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ -} dcd_data_t; - -/*------------------------------------------------------------------ - * INTERNAL OBJECT & FUNCTION DECLARATION - *------------------------------------------------------------------*/ -static dcd_data_t _dcd; - - -static volatile void *edpt_get_fifo_ptr(unsigned epnum) { - volatile uint32_t *ptr; - - ptr = &MXC_USBHS->fifo0; - ptr += epnum; /* Pointer math: multiplies ep by sizeof(uint32_t) */ - - return (volatile void *) ptr; -} - -static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { - volatile hw_fifo_t *reg = (volatile hw_fifo_t *) fifo; - uintptr_t addr = (uintptr_t) buf; - while (len >= 4) { - reg->u32 = *(uint32_t const *) addr; - addr += 4; - len -= 4; - } - if (len >= 2) { - reg->u16 = *(uint16_t const *) addr; - addr += 2; - len -= 2; - } - if (len) { - reg->u8 = *(uint8_t const *) addr; - } -} - -static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) { - volatile hw_fifo_t *reg = (volatile hw_fifo_t *) fifo; - uintptr_t addr = (uintptr_t) buf; - while (len >= 4) { - *(uint32_t *) addr = reg->u32; - addr += 4; - len -= 4; - } - if (len >= 2) { - *(uint16_t *) addr = reg->u16; - addr += 2; - len -= 2; - } - if (len) { - *(uint8_t *) addr = reg->u8; - } -} - -static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir) { - static const struct { - void (*tu_fifo_get_info)(tu_fifo_t *f, tu_fifo_buffer_info_t *info); - void (*tu_fifo_advance)(tu_fifo_t *f, uint16_t n); - void (*pipe_read_write)(void *buf, volatile void *fifo, unsigned len); - } ops[] = { - /* OUT */ {tu_fifo_get_write_info, tu_fifo_advance_write_pointer, pipe_read_packet}, - /* IN */ {tu_fifo_get_read_info, tu_fifo_advance_read_pointer, pipe_write_packet}, - }; - tu_fifo_buffer_info_t info; - ops[dir].tu_fifo_get_info(f, &info); - unsigned total_len = len; - len = TU_MIN(total_len, info.len_lin); - ops[dir].pipe_read_write(info.ptr_lin, fifo, len); - unsigned rem = total_len - len; - if (rem) { - len = TU_MIN(rem, info.len_wrap); - ops[dir].pipe_read_write(info.ptr_wrap, fifo, len); - rem -= len; - } - ops[dir].tu_fifo_advance(f, total_len - rem); -} - -static void process_setup_packet(uint8_t rhport) { - uint32_t *p = (void *) &_dcd.setup_packet; - p[0] = MXC_USBHS->fifo0; - p[1] = MXC_USBHS->fifo0; - - _dcd.pipe0.buf = NULL; - _dcd.pipe0.length = 0; - _dcd.pipe0.remaining = 0; - dcd_event_setup_received(rhport, (const uint8_t *) (uintptr_t) &_dcd.setup_packet, true); - - const unsigned len = _dcd.setup_packet.wLength; - _dcd.remaining_ctrl = len; - const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); - /* Clear RX FIFO and reverse the transaction direction */ - if (len && dir_in) { - MXC_USBHS->index = 0; - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY; - } -} - -static bool handle_xfer_in(uint_fast8_t ep_addr) { - unsigned epnum = tu_edpt_number(ep_addr); - unsigned epnum_minus1 = epnum - 1; - pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; - const unsigned rem = pipe->remaining; - - //This function should not be for ep0 - TU_ASSERT(epnum); - - if (!rem) { - pipe->buf = NULL; - return true; - } - - MXC_USBHS->index = epnum; - const unsigned mps = MXC_USBHS->inmaxp; - const unsigned len = TU_MIN(mps, rem); - void *buf = pipe->buf; - volatile void *fifo_ptr = edpt_get_fifo_ptr(epnum); - if (len) { - if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { - pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_IN); - } else { - pipe_write_packet(buf, fifo_ptr, len); - pipe->buf = buf + len; - } - pipe->remaining = rem - len; - } - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_INPKTRDY;//TODO: Verify a | isn't needed - - return false; -} - -static bool handle_xfer_out(uint_fast8_t ep_addr) { - unsigned epnum = tu_edpt_number(ep_addr); - unsigned epnum_minus1 = epnum - 1; - pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; - - //This function should not be for ep0 - TU_ASSERT(epnum); - - MXC_USBHS->index = epnum; - - TU_ASSERT(MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY); - - const unsigned mps = MXC_USBHS->outmaxp; - const unsigned rem = pipe->remaining; - const unsigned vld = MXC_USBHS->outcount; - const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); - void *buf = pipe->buf; - volatile void *fifo_ptr = edpt_get_fifo_ptr(epnum); - if (len) { - if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { - pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_OUT); - } else { - pipe_read_packet(buf, fifo_ptr, len); - pipe->buf = buf + len; - } - pipe->remaining = rem - len; - } - if ((len < mps) || (rem == len)) { - pipe->buf = NULL; - return NULL != buf; - } - MXC_USBHS->outcsrl = 0; /* Clear RXRDY bit *///TODO: Verify just setting to 0 is ok - return false; -} - -static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - (void) rhport; - - unsigned epnum = tu_edpt_number(ep_addr); - unsigned epnum_minus1 = epnum - 1; - unsigned dir_in = tu_edpt_dir(ep_addr); - - pipe_state_t *pipe = &_dcd.pipe[dir_in][epnum_minus1]; - pipe->buf = buffer; - pipe->length = total_bytes; - pipe->remaining = total_bytes; - - if (dir_in) { - handle_xfer_in(ep_addr); - } else { - MXC_USBHS->index = epnum; - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { - MXC_USBHS->outcsrl = 0;//TODO: Verify just setting to 0 is ok - } - } - return true; -} - -static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - (void) rhport; - TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ - - const unsigned req = _dcd.setup_packet.bmRequestType; - TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); - - if (req == REQUEST_TYPE_INVALID || _dcd.status_out) { - /* STATUS OUT stage. - * MUSB controller automatically handles STATUS OUT packets without - * software helps. We do not have to do anything. And STATUS stage - * may have already finished and received the next setup packet - * without calling this function, so we have no choice but to - * invoke the callback function of status packet here. */ - _dcd.status_out = 0; - if (req == REQUEST_TYPE_INVALID) { - dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); - } else { - /* The next setup packet has already been received, it aborts - * invoking callback function to avoid confusing TUSB stack. */ - TU_LOG1("Drop CONTROL_STAGE_ACK\r\n"); - } - return true; - } - const unsigned dir_in = tu_edpt_dir(ep_addr); - MXC_USBHS->index = 0; - if (tu_edpt_dir(req) == dir_in) { /* DATA stage */ - TU_ASSERT(total_bytes <= _dcd.remaining_ctrl); - const unsigned rem = _dcd.remaining_ctrl; - const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes); - volatile void *fifo_ptr = edpt_get_fifo_ptr(0); - if (dir_in) { - pipe_write_packet(buffer, fifo_ptr, len); - - _dcd.pipe0.buf = buffer + len; - _dcd.pipe0.length = len; - _dcd.pipe0.remaining = 0; - - _dcd.remaining_ctrl = rem - len; - if ((len < 64) || (rem == len)) { - _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ - _dcd.status_out = 1; - /* Flush TX FIFO and reverse the transaction direction. */ - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_INPKTRDY | MXC_F_USBHS_CSR0_DATA_END; - } else { - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_INPKTRDY; /* Flush TX FIFO to return ACK. */ - } - } else { - _dcd.pipe0.buf = buffer; - _dcd.pipe0.length = len; - _dcd.pipe0.remaining = len; - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY; /* Clear RX FIFO to return ACK. */ - } - } else if (dir_in) { - _dcd.pipe0.buf = NULL; - _dcd.pipe0.length = 0; - _dcd.pipe0.remaining = 0; - /* Clear RX FIFO and reverse the transaction direction */ - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY | MXC_F_USBHS_CSR0_DATA_END; - } - return true; -} - -static void process_ep0(uint8_t rhport) { - MXC_USBHS->index = 0; - uint_fast8_t csrl = MXC_USBHS->csr0; - - if (csrl & MXC_F_USBHS_CSR0_SENT_STALL) { - /* Returned STALL packet to HOST. */ - MXC_USBHS->csr0 = 0; /* Clear STALL */ - return; - } - - unsigned req = _dcd.setup_packet.bmRequestType; - if (csrl & MXC_F_USBHS_CSR0_SETUP_END) { - TU_LOG1(" ABORT by the next packets\r\n"); - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_SETUP_END; - if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { - /* DATA stage was aborted by receiving STATUS or SETUP packet. */ - _dcd.pipe0.buf = NULL; - _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; - dcd_event_xfer_complete(rhport, - req & TUSB_DIR_IN_MASK, - _dcd.pipe0.length - _dcd.pipe0.remaining, - XFER_RESULT_SUCCESS, true); - } - req = REQUEST_TYPE_INVALID; - if (!(csrl & MXC_F_USBHS_CSR0_OUTPKTRDY)) return; /* Received SETUP packet */ - } - - if (csrl & MXC_F_USBHS_CSR0_OUTPKTRDY) { - /* Received SETUP or DATA OUT packet */ - if (req == REQUEST_TYPE_INVALID) { - /* SETUP */ - TU_ASSERT(sizeof(tusb_control_request_t) == MXC_USBHS->count0, ); - process_setup_packet(rhport); - return; - } - if (_dcd.pipe0.buf) { - /* DATA OUT */ - const unsigned vld = MXC_USBHS->count0; - const unsigned rem = _dcd.pipe0.remaining; - const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); - volatile void *fifo_ptr = edpt_get_fifo_ptr(0); - pipe_read_packet(_dcd.pipe0.buf, fifo_ptr, len); - - _dcd.pipe0.remaining = rem - len; - _dcd.remaining_ctrl -= len; - - _dcd.pipe0.buf = NULL; - dcd_event_xfer_complete(rhport, - tu_edpt_addr(0, TUSB_DIR_OUT), - _dcd.pipe0.length - _dcd.pipe0.remaining, - XFER_RESULT_SUCCESS, true); - } - return; - } - - /* When CSRL0 is zero, it means that completion of sending a any length packet - * or receiving a zero length packet. */ - if (req != REQUEST_TYPE_INVALID && !tu_edpt_dir(req)) { - /* STATUS IN */ - if (*(const uint16_t *) (uintptr_t) &_dcd.setup_packet == 0x0500) { - /* The address must be changed on completion of the control transfer. */ - MXC_USBHS->faddr = (uint8_t) _dcd.setup_packet.wValue; - } - _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; - dcd_event_xfer_complete(rhport, - tu_edpt_addr(0, TUSB_DIR_IN), - _dcd.pipe0.length - _dcd.pipe0.remaining, - XFER_RESULT_SUCCESS, true); - return; - } - if (_dcd.pipe0.buf) { - /* DATA IN */ - _dcd.pipe0.buf = NULL; - dcd_event_xfer_complete(rhport, - tu_edpt_addr(0, TUSB_DIR_IN), - _dcd.pipe0.length - _dcd.pipe0.remaining, - XFER_RESULT_SUCCESS, true); - } -} - -static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) { - bool completed; - const unsigned dir_in = tu_edpt_dir(ep_addr); - const unsigned epnum = tu_edpt_number(ep_addr); - - MXC_USBHS->index = epnum; - - if (dir_in) { - if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_SENTSTALL) { - MXC_USBHS->incsrl &= ~(MXC_F_USBHS_INCSRL_SENTSTALL | MXC_F_USBHS_INCSRL_UNDERRUN); - return; - } - completed = handle_xfer_in(ep_addr); - } else { - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_SENTSTALL) { - MXC_USBHS->outcsrl &= ~(MXC_F_USBHS_OUTCSRL_SENTSTALL | MXC_F_USBHS_OUTCSRL_OVERRUN); - return; - } - completed = handle_xfer_out(ep_addr); - } - - if (completed) { - pipe_state_t *pipe = &_dcd.pipe[dir_in][tu_edpt_number(ep_addr) - 1]; - dcd_event_xfer_complete(rhport, ep_addr, - pipe->length - pipe->remaining, - XFER_RESULT_SUCCESS, true); - } -} - -static void process_bus_reset(uint8_t rhport) { - (void) rhport; - /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), - * a control transfer state is SETUP or STATUS stage. */ - _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; - _dcd.status_out = 0; - /* When pipe0.buf has not NULL, DATA stage works in progress. */ - _dcd.pipe0.buf = NULL; - - MXC_USBHS->intrinen = 1; /* Enable only EP0 */ - MXC_USBHS->introuten = 0; - - - /* Clear FIFO settings */ - for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - MXC_USBHS->index = i; - if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { - /* Per musbhsfc_pg, only flush FIFO if IN packet loaded */ - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_FLUSHFIFO; - } - - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { - /* Per musbhsfc_pg, only flush FIFO if OUT packet is ready */ - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_FLUSHFIFO; - } - } - dcd_event_bus_reset(0, (MXC_USBHS->power & MXC_F_USBHS_POWER_HS_MODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); -} - -/*------------------------------------------------------------------ - * Device API - *------------------------------------------------------------------*/ - -void dcd_init(uint8_t rhport) { - (void) rhport; - MXC_USBHS->intrusben |= MXC_F_USBHS_INTRUSBEN_SUSPEND_INT_EN; - - //Interrupt for VBUS disconnect - MXC_USBHS->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS; - - NVIC_ClearPendingIRQ(USB_IRQn); - dcd_edpt_close_all(rhport); - - //Unsuspend the MAC - MXC_USBHS->mxm_suspend = 0; - - /* Configure PHY */ - MXC_USBHS->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11); - MXC_USBHS->m31_phy_xcfgi_63_32 = 0; - MXC_USBHS->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64); - MXC_USBHS->m31_phy_xcfgi_127_96 = 0; - - - #ifdef USBHS_M31_CLOCK_RECOVERY - MXC_USBHS->m31_phy_noncry_rstb = 1; - MXC_USBHS->m31_phy_noncry_en = 1; - MXC_USBHS->m31_phy_outclksel = 0; - MXC_USBHS->m31_phy_coreclkin = 0; - MXC_USBHS->m31_phy_xtlsel = 2; /* Select 25 MHz clock */ - #else - /* Use this option to feed the PHY a 30 MHz clock, which is them used as a PLL reference */ - /* As it depends on the system core clock, this should probably be done at the SYS level */ - MXC_USBHS->m31_phy_noncry_rstb = 0; - MXC_USBHS->m31_phy_noncry_en = 0; - MXC_USBHS->m31_phy_outclksel = 1; - MXC_USBHS->m31_phy_coreclkin = 1; - MXC_USBHS->m31_phy_xtlsel = 3; /* Select 30 MHz clock */ - #endif - MXC_USBHS->m31_phy_pll_en = 1; - MXC_USBHS->m31_phy_oscouten = 1; - - /* Reset PHY */ - MXC_USBHS->m31_phy_ponrst = 0; - MXC_USBHS->m31_phy_ponrst = 1; - - dcd_connect(rhport); -} - -void dcd_int_enable(uint8_t rhport) { - (void) rhport; - NVIC_EnableIRQ(USB_IRQn); -} - -void dcd_int_disable(uint8_t rhport) { - (void) rhport; - NVIC_DisableIRQ(USB_IRQn); -} - -// Receive Set Address request, mcu port must also include status IN response -void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { - (void) rhport; - (void) dev_addr; - _dcd.pipe0.buf = NULL; - _dcd.pipe0.length = 0; - _dcd.pipe0.remaining = 0; - /* Clear RX FIFO to return ACK. */ - MXC_USBHS->index = 0; - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY | MXC_F_USBHS_CSR0_DATA_END; -} - -// Wake up host -void dcd_remote_wakeup(uint8_t rhport) { - (void) rhport; - MXC_USBHS->power |= MXC_F_USBHS_POWER_RESUME; - - #if CFG_TUSB_OS != OPT_OS_NONE - osal_task_delay(10); - #else - MXC_Delay(MXC_DELAY_MSEC(10)); - #endif - - MXC_USBHS->power &= ~MXC_F_USBHS_POWER_RESUME; -} - -// Connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(uint8_t rhport) { - (void) rhport; - MXC_USBHS->power |= TUD_OPT_HIGH_SPEED ? MXC_F_USBHS_POWER_HS_ENABLE : 0; - MXC_USBHS->power |= MXC_F_USBHS_POWER_SOFTCONN; -} - -// Disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(uint8_t rhport) { - (void) rhport; - MXC_USBHS->power &= ~MXC_F_USBHS_POWER_SOFTCONN; -} - -void dcd_sof_enable(uint8_t rhport, bool en) { - (void) rhport; - (void) en; - - // TODO implement later -} - -//--------------------------------------------------------------------+ -// Endpoint API -//--------------------------------------------------------------------+ - -// Configure endpoint's registers according to descriptor -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) { - (void) rhport; - - const unsigned ep_addr = ep_desc->bEndpointAddress; - const unsigned epn = tu_edpt_number(ep_addr); - const unsigned dir_in = tu_edpt_dir(ep_addr); - const unsigned xfer = ep_desc->bmAttributes.xfer; - const unsigned mps = tu_edpt_packet_size(ep_desc); - - TU_ASSERT(epn < TUP_DCD_ENDPOINT_MAX); - - pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; - pipe->buf = NULL; - pipe->length = 0; - pipe->remaining = 0; - - MXC_USBHS->index = epn; - - if (dir_in) { - MXC_USBHS->inmaxp = mps; - MXC_USBHS->incsru = (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE) | ((xfer == TUSB_XFER_ISOCHRONOUS) ? MXC_F_USBHS_INCSRU_ISO : 0); - if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; - } else { - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; - } - MXC_USBHS->intrinen |= TU_BIT(epn); - } else { - MXC_USBHS->outmaxp = mps; - MXC_USBHS->outcsru = (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS) | ((xfer == TUSB_XFER_ISOCHRONOUS) ? MXC_F_USBHS_OUTCSRU_ISO : 0); - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; - } else { - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; - } - MXC_USBHS->introuten |= TU_BIT(epn); - } - - return true; -} - -void dcd_edpt_close_all(uint8_t rhport) { - (void) rhport; - - MXC_SYS_Crit_Enter(); - MXC_USBHS->intrinen = 1; /* Enable only EP0 */ - MXC_USBHS->introuten = 0; - - for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - MXC_USBHS->index = i; - MXC_USBHS->inmaxp = 0; - MXC_USBHS->incsru = MXC_F_USBHS_INCSRU_DPKTBUFDIS; - - if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; - } else { - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; - } - - MXC_USBHS->outmaxp = 0; - MXC_USBHS->outcsru = MXC_F_USBHS_OUTCSRU_DPKTBUFDIS; - - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; - } else { - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; - } - } - MXC_SYS_Crit_Exit(); -} - -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - unsigned const epn = tu_edpt_number(ep_addr); - unsigned const dir_in = tu_edpt_dir(ep_addr); - - MXC_SYS_Crit_Enter(); - MXC_USBHS->index = epn; - if (dir_in) { - MXC_USBHS->intrinen &= ~TU_BIT(epn); - MXC_USBHS->inmaxp = 0; - MXC_USBHS->incsru = MXC_F_USBHS_INCSRU_DPKTBUFDIS; - if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; - } else { - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; - } - } else { - MXC_USBHS->introuten &= ~TU_BIT(epn); - MXC_USBHS->outmaxp = 0; - MXC_USBHS->outcsru = MXC_F_USBHS_OUTCSRU_DPKTBUFDIS; - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; - } else { - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; - } - } - MXC_SYS_Crit_Exit(); -} - -// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - (void) rhport; - bool ret; - unsigned const epnum = tu_edpt_number(ep_addr); - MXC_SYS_Crit_Enter(); - if (epnum) { - _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); - ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); - } else - ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); - MXC_SYS_Crit_Exit(); - return ret; -} - -// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c -bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) { - (void) rhport; - bool ret; - unsigned const epnum = tu_edpt_number(ep_addr); - TU_ASSERT(epnum); - MXC_SYS_Crit_Enter(); - _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] |= TU_BIT(epnum - 1); - ret = edpt_n_xfer(rhport, ep_addr, (uint8_t *) ff, total_bytes); - MXC_SYS_Crit_Exit(); - return ret; -} - -// Stall endpoint -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - unsigned const epn = tu_edpt_number(ep_addr); - MXC_SYS_Crit_Enter(); - MXC_USBHS->index = epn; - if (0 == epn) { - if (!ep_addr) { /* Ignore EP80 */ - _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; - _dcd.pipe0.buf = NULL; - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SEND_STALL; - } - } else { - if (tu_edpt_dir(ep_addr)) { /* IN */ - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_SENDSTALL; - } else { /* OUT */ - TU_ASSERT(!(MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY), ); - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_SENDSTALL; - } - } - MXC_SYS_Crit_Exit(); -} - -// clear stall, data toggle is also reset to DATA0 -void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - unsigned const epn = tu_edpt_number(ep_addr); - MXC_SYS_Crit_Enter(); - MXC_USBHS->index = epn; - if (tu_edpt_dir(ep_addr)) { /* IN */ - /* IN endpoint */ - if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { - /* Per musbhsfc_pg, only flush FIFO if IN packet loaded */ - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; - } else { - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; - } - } else { /* OUT */ - /* Otherwise, must be OUT endpoint */ - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { - /* Per musbhsfc_pg, only flush FIFO if OUT packet is ready */ - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; - } else { - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; - } - } - MXC_SYS_Crit_Exit(); -} - -/*------------------------------------------------------------------- - * ISR - *-------------------------------------------------------------------*/ -void dcd_int_handler(uint8_t rhport) { - uint_fast8_t is, txis, rxis; - uint32_t mxm_int, mxm_int_en, mxm_is; - uint32_t saved_index; - - /* Save current index register */ - saved_index = MXC_USBHS->index; - - is = MXC_USBHS->intrusb; /* read and clear interrupt status */ - txis = MXC_USBHS->intrin; /* read and clear interrupt status */ - rxis = MXC_USBHS->introut; /* read and clear interrupt status */ - - /* These USB interrupt flags are W1C. */ - /* Order of volatile accesses must be separated for IAR */ - mxm_int = MXC_USBHS->mxm_int; - mxm_int_en = MXC_USBHS->mxm_int_en; - mxm_is = mxm_int & mxm_int_en; - MXC_USBHS->mxm_int = mxm_is; - - is &= MXC_USBHS->intrusben; /* Clear disabled interrupts */ - - if (mxm_is & MXC_F_USBHS_MXM_INT_NOVBUS) { - dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); - } - if (is & MXC_F_USBHS_INTRUSB_SOF_INT) { - dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); - } - if (is & MXC_F_USBHS_INTRUSB_RESET_INT) { - process_bus_reset(rhport); - } - if (is & MXC_F_USBHS_INTRUSB_RESUME_INT) { - dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); - } - if (is & MXC_F_USBHS_INTRUSB_SUSPEND_INT) { - dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); - } - - txis &= MXC_USBHS->intrinen; /* Clear disabled interrupts */ - if (txis & MXC_F_USBHS_INTRIN_EP0_IN_INT) { - process_ep0(rhport); - txis &= ~TU_BIT(0); - } - while (txis) { - unsigned const num = __builtin_ctz(txis); - process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN)); - txis &= ~TU_BIT(num); - } - rxis &= MXC_USBHS->introuten; /* Clear disabled interrupts */ - while (rxis) { - unsigned const num = __builtin_ctz(rxis); - process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT)); - rxis &= ~TU_BIT(num); - } - - /* Restore register index before exiting ISR */ - MXC_USBHS->index = saved_index; -} - -#endif diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index a817c5d6e..ee36656fd 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2021 Koji KITAYAMA + * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,8 +27,7 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && \ - TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) +#if CFG_TUD_ENABLED #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) /* GCC warns that an address may be unaligned, even though @@ -35,43 +35,30 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); #endif +#include "musb_type.h" #include "device/dcd.h" -#if TU_CHECK_MCU(OPT_MCU_MSP432E4) - #include "musb_msp432e.h" - -#elif TU_CHECK_MCU(OPT_MCU_TM4C123, OPT_MCU_TM4C129) - #include "musb_tm4c.h" - - // HACK generalize later - #include "musb_type.h" - #define FIFO0_WORD FIFO0 - #define FIFO1_WORD FIFO1 - +// Following symbols must be defined by port header +// - musb_dcd_int_enable/disable/clear/get_enable +// - musb_dcd_int_handler_enter/exit +// - musb_dcd_epn_regs: Get memory mapped struct of end point registers +// - musb_dcd_ep0_regs: Get memory mapped struct of EP0 registers +// - musb_dcd_ctl_regs: Get memory mapped struct of control registers +// - musb_dcd_ep_get_fifo_ptr: Gets the address of the provided EP's FIFO +// - musb_dcd_setup_fifo/reset_fifo: Configuration of the EP's FIFO +#if TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) + #include "musb_ti.h" +#elif TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002) + #include "musb_max32.h" #else - #error "Unsupported MCUs" + #error "Unsupported MCU" #endif /*------------------------------------------------------------------ * MACRO TYPEDEF CONSTANT ENUM DECLARATION *------------------------------------------------------------------*/ -#define REQUEST_TYPE_INVALID (0xFFu) -typedef struct { - uint_fast16_t beg; /* offset of including first element */ - uint_fast16_t end; /* offset of excluding the last element */ -} free_block_t; - -typedef struct TU_ATTR_PACKED { - uint16_t TXMAXP; - uint8_t TXCSRL; - uint8_t TXCSRH; - uint16_t RXMAXP; - uint8_t RXCSRL; - uint8_t RXCSRH; - uint16_t RXCOUNT; - uint16_t RESERVED[3]; -} hw_endpoint_t; +#define REQUEST_TYPE_INVALID (0xFFu) typedef union { uint8_t u8; @@ -92,7 +79,7 @@ typedef struct uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ int8_t status_out; pipe_state_t pipe0; - pipe_state_t pipe[2][7]; /* pipe[direction][endpoint number - 1] */ + pipe_state_t pipe[2][TUP_DCD_ENDPOINT_MAX-1]; /* pipe[direction][endpoint number - 1] */ uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ } dcd_data_t; @@ -102,126 +89,6 @@ typedef struct static dcd_data_t _dcd; -static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) -{ - free_block_t *cur = beg; - for (; cur < end && ((addr < cur->beg) || (cur->end <= addr)); ++cur) ; - return cur; -} - -static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) -{ - free_block_t *p = find_containing_block(blks, blks + num, addr); - TU_ASSERT(p != blks + num, -2); - if (p->beg == addr) { - /* Shrink block */ - p->beg = addr + size; - if (p->beg != p->end) return 0; - /* remove block */ - free_block_t *end = blks + num; - while (p + 1 < end) { - *p = *(p + 1); - ++p; - } - return -1; - } else { - /* Split into 2 blocks */ - free_block_t tmp = { - .beg = addr + size, - .end = p->end - }; - p->end = addr; - if (p->beg == p->end) { - if (tmp.beg != tmp.end) { - *p = tmp; - return 0; - } - /* remove block */ - free_block_t *end = blks + num; - while (p + 1 < end) { - *p = *(p + 1); - ++p; - } - return -1; - } - if (tmp.beg == tmp.end) return 0; - blks[num] = tmp; - return 1; - } -} - -static inline unsigned free_block_size(free_block_t const *blk) -{ - return blk->end - blk->beg; -} - -#if 0 -static inline void print_block_list(free_block_t const *blk, unsigned num) -{ - TU_LOG1("*************\r\n"); - for (unsigned i = 0; i < num; ++i) { - TU_LOG1(" Blk%u %u %u\r\n", i, blk->beg, blk->end); - ++blk; - } -} -#else -#define print_block_list(a,b) -#endif - -static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) -{ - free_block_t free_blocks[2 * (TUP_DCD_ENDPOINT_MAX - 1)]; - unsigned num_blocks = 1; - - /* Initialize free memory block list */ - free_blocks[0].beg = 64 / 8; - free_blocks[0].end = (4 << 10) / 8; /* 4KiB / 8 bytes */ - for (int i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - uint_fast16_t addr; - int num; - USB0->EPIDX = i; - addr = USB0->TXFIFOADD; - if (addr) { - unsigned sz = USB0->TXFIFOSZ; - unsigned sft = (sz & USB_TXFIFOSZ_SIZE_M) + ((sz & USB_TXFIFOSZ_DPB) ? 1: 0); - num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); - TU_ASSERT(-2 < num, 0); - num_blocks += num; - print_block_list(free_blocks, num_blocks); - } - addr = USB0->RXFIFOADD; - if (addr) { - unsigned sz = USB0->RXFIFOSZ; - unsigned sft = (sz & USB_RXFIFOSZ_SIZE_M) + ((sz & USB_RXFIFOSZ_DPB) ? 1: 0); - num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); - TU_ASSERT(-2 < num, 0); - num_blocks += num; - print_block_list(free_blocks, num_blocks); - } - } - print_block_list(free_blocks, num_blocks); - - /* Find the best fit memory block */ - uint_fast16_t size_in_8byte_unit = 1 << size_in_log2_minus3; - free_block_t const *min = NULL; - uint_fast16_t min_sz = 0xFFFFu; - free_block_t const *end = &free_blocks[num_blocks]; - for (free_block_t const *cur = &free_blocks[0]; cur < end; ++cur) { - uint_fast16_t sz = free_block_size(cur); - if (sz < size_in_8byte_unit) continue; - if (size_in_8byte_unit == sz) return cur->beg; - if (sz < min_sz) min = cur; - } - TU_ASSERT(min, 0); - return min->beg; -} - -static inline volatile hw_endpoint_t* edpt_regs(unsigned epnum_minus1) -{ - volatile hw_endpoint_t *regs = (volatile hw_endpoint_t*)((uintptr_t)&USB0->TXMAXP1); - return regs + epnum_minus1; -} - static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; @@ -287,8 +154,10 @@ static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigne static void process_setup_packet(uint8_t rhport) { uint32_t *p = (void*)&_dcd.setup_packet; - p[0] = USB0->FIFO0_WORD; - p[1] = USB0->FIFO0_WORD; + volatile uint32_t *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, 0); + volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + p[0] = *fifo_ptr; + p[1] = *fifo_ptr; _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; @@ -299,12 +168,13 @@ static void process_setup_packet(uint8_t rhport) _dcd.remaining_ctrl = len; const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); /* Clear RX FIFO and reverse the transaction direction */ - if (len && dir_in) USB0->CSRL0 = USB_CSRL0_RXRDYC; + if (len && dir_in) ep0_regs->CSRL0 = USB_CSRL0_RXRDYC; } -static bool handle_xfer_in(uint_fast8_t ep_addr) +static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) { - unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; + unsigned epnum = tu_edpt_number(ep_addr); + unsigned epnum_minus1 = epnum - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; const unsigned rem = pipe->remaining; @@ -313,30 +183,32 @@ static bool handle_xfer_in(uint_fast8_t ep_addr) return true; } - volatile hw_endpoint_t *regs = edpt_regs(epnum_minus1); + volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); const unsigned mps = regs->TXMAXP; const unsigned len = TU_MIN(mps, rem); void *buf = pipe->buf; + volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, epnum); // TU_LOG1(" %p mps %d len %d rem %d\r\n", buf, mps, len, rem); if (len) { if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { - pipe_read_write_packet_ff(buf, &USB0->FIFO1_WORD + epnum_minus1, len, TUSB_DIR_IN); + pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_IN); } else { - pipe_write_packet(buf, &USB0->FIFO1_WORD + epnum_minus1, len); + pipe_write_packet(buf, fifo_ptr, len); pipe->buf = buf + len; } pipe->remaining = rem - len; } regs->TXCSRL = USB_TXCSRL1_TXRDY; - // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum_minus1 + 1, regs->TXCSRL, rem - len); + // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum, regs->TXCSRL, rem - len); return false; } -static bool handle_xfer_out(uint_fast8_t ep_addr) +static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) { - unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; + unsigned epnum = tu_edpt_number(ep_addr); + unsigned epnum_minus1 = epnum - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; - volatile hw_endpoint_t *regs = edpt_regs(epnum_minus1); + volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, regs->RXCSRL); TU_ASSERT(regs->RXCSRL & USB_RXCSRL1_RXRDY); @@ -346,11 +218,12 @@ static bool handle_xfer_out(uint_fast8_t ep_addr) const unsigned vld = regs->RXCOUNT; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); void *buf = pipe->buf; + volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, epnum); if (len) { if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { - pipe_read_write_packet_ff(buf, &USB0->FIFO1_WORD + epnum_minus1, len, TUSB_DIR_OUT); + pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_OUT); } else { - pipe_read_packet(buf, &USB0->FIFO1_WORD + epnum_minus1, len); + pipe_read_packet(buf, fifo_ptr, len); pipe->buf = buf + len; } pipe->remaining = rem - len; @@ -365,9 +238,8 @@ static bool handle_xfer_out(uint_fast8_t ep_addr) static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - (void)rhport; - - unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; + unsigned epnum = tu_edpt_number(ep_addr); + unsigned epnum_minus1 = epnum - 1; unsigned dir_in = tu_edpt_dir(ep_addr); pipe_state_t *pipe = &_dcd.pipe[dir_in][epnum_minus1]; @@ -376,9 +248,9 @@ static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16 pipe->remaining = total_bytes; if (dir_in) { - handle_xfer_in(ep_addr); + handle_xfer_in(rhport, ep_addr); } else { - volatile hw_endpoint_t *regs = edpt_regs(epnum_minus1); + volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); if (regs->RXCSRL & USB_RXCSRL1_RXRDY) regs->RXCSRL = 0; } return true; @@ -388,7 +260,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ { (void)rhport; TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ - + volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); const unsigned req = _dcd.setup_packet.bmRequestType; TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); @@ -399,7 +271,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ * may have already finished and received the next setup packet * without calling this function, so we have no choice but to * invoke the callback function of status packet here. */ - // TU_LOG1(" STATUS OUT USB0->CSRL0 = %x\r\n", USB0->CSRL0); + // TU_LOG1(" STATUS OUT ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); _dcd.status_out = 0; if (req == REQUEST_TYPE_INVALID) { dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); @@ -415,8 +287,9 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ TU_ASSERT(total_bytes <= _dcd.remaining_ctrl); const unsigned rem = _dcd.remaining_ctrl; const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes); + volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, 0); if (dir_in) { - pipe_write_packet(buffer, &USB0->FIFO0_WORD, len); + pipe_write_packet(buffer, fifo_ptr, len); _dcd.pipe0.buf = buffer + len; _dcd.pipe0.length = len; @@ -427,45 +300,46 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ _dcd.status_out = 1; /* Flush TX FIFO and reverse the transaction direction. */ - USB0->CSRL0 = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND; + ep0_regs->CSRL0 = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND; } else { - USB0->CSRL0 = USB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ + ep0_regs->CSRL0 = USB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ } - // TU_LOG1(" IN USB0->CSRL0 = %x\r\n", USB0->CSRL0); + // TU_LOG1(" IN ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); } else { - // TU_LOG1(" OUT USB0->CSRL0 = %x\r\n", USB0->CSRL0); + // TU_LOG1(" OUT ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); _dcd.pipe0.buf = buffer; _dcd.pipe0.length = len; _dcd.pipe0.remaining = len; - USB0->CSRL0 = USB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ + ep0_regs->CSRL0 = USB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ } } else if (dir_in) { - // TU_LOG1(" STATUS IN USB0->CSRL0 = %x\r\n", USB0->CSRL0); + // TU_LOG1(" STATUS IN ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO and reverse the transaction direction */ - USB0->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; + ep0_regs->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; } return true; } static void process_ep0(uint8_t rhport) { - uint_fast8_t csrl = USB0->CSRL0; + volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + uint_fast8_t csrl = ep0_regs->CSRL0; - // TU_LOG1(" EP0 USB0->CSRL0 = %x\r\n", csrl); + // TU_LOG1(" EP0 ep0_regs->CSRL0 = %x\r\n", csrl); if (csrl & USB_CSRL0_STALLED) { /* Returned STALL packet to HOST. */ - USB0->CSRL0 = 0; /* Clear STALL */ + ep0_regs->CSRL0 = 0; /* Clear STALL */ return; } unsigned req = _dcd.setup_packet.bmRequestType; if (csrl & USB_CSRL0_SETEND) { TU_LOG1(" ABORT by the next packets\r\n"); - USB0->CSRL0 = USB_CSRL0_SETENDC; + ep0_regs->CSRL0 = USB_CSRL0_SETENDC; if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { /* DATA stage was aborted by receiving STATUS or SETUP packet. */ _dcd.pipe0.buf = NULL; @@ -483,16 +357,17 @@ static void process_ep0(uint8_t rhport) /* Received SETUP or DATA OUT packet */ if (req == REQUEST_TYPE_INVALID) { /* SETUP */ - TU_ASSERT(sizeof(tusb_control_request_t) == USB0->COUNT0,); + TU_ASSERT(sizeof(tusb_control_request_t) == ep0_regs->COUNT0,); process_setup_packet(rhport); return; } if (_dcd.pipe0.buf) { /* DATA OUT */ - const unsigned vld = USB0->COUNT0; + const unsigned vld = ep0_regs->COUNT0; const unsigned rem = _dcd.pipe0.remaining; const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); - pipe_read_packet(_dcd.pipe0.buf, &USB0->FIFO0_WORD, len); + volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, 0); + pipe_read_packet(_dcd.pipe0.buf, fifo_ptr, len); _dcd.pipe0.remaining = rem - len; _dcd.remaining_ctrl -= len; @@ -506,13 +381,15 @@ static void process_ep0(uint8_t rhport) return; } + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + /* When CSRL0 is zero, it means that completion of sending a any length packet * or receiving a zero length packet. */ if (req != REQUEST_TYPE_INVALID && !tu_edpt_dir(req)) { /* STATUS IN */ if (*(const uint16_t*)(uintptr_t)&_dcd.setup_packet == 0x0500) { /* The address must be changed on completion of the control transfer. */ - USB0->FADDR = (uint8_t)_dcd.setup_packet.wValue; + ctrl_regs->FADDR = (uint8_t)_dcd.setup_packet.wValue; } _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; dcd_event_xfer_complete(rhport, @@ -535,27 +412,28 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) { bool completed; const unsigned dir_in = tu_edpt_dir(ep_addr); - const unsigned epn_minus1 = tu_edpt_number(ep_addr) - 1; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned epn_minus1 = epn - 1; - volatile hw_endpoint_t *regs = edpt_regs(epn_minus1); + volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); if (dir_in) { - // TU_LOG1(" TXCSRL%d = %x\r\n", epn_minus1 + 1, regs->TXCSRL); + // TU_LOG1(" TXCSRL%d = %x\r\n", epn, regs->TXCSRL); if (regs->TXCSRL & USB_TXCSRL1_STALLED) { regs->TXCSRL &= ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_UNDRN); return; } - completed = handle_xfer_in(ep_addr); + completed = handle_xfer_in(rhport, ep_addr); } else { - // TU_LOG1(" RXCSRL%d = %x\r\n", epn_minus1 + 1, regs->RXCSRL); + // TU_LOG1(" RXCSRL%d = %x\r\n", epn, regs->RXCSRL); if (regs->RXCSRL & USB_RXCSRL1_STALLED) { regs->RXCSRL &= ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_OVER); return; } - completed = handle_xfer_out(ep_addr); + completed = handle_xfer_out(rhport, ep_addr); } if (completed) { - pipe_state_t *pipe = &_dcd.pipe[dir_in][tu_edpt_number(ep_addr) - 1]; + pipe_state_t *pipe = &_dcd.pipe[dir_in][epn_minus1]; dcd_event_xfer_complete(rhport, ep_addr, pipe->length - pipe->remaining, XFER_RESULT_SUCCESS, true); @@ -564,6 +442,7 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) static void process_bus_reset(uint8_t rhport) { + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), * a control transfer state is SETUP or STATUS stage. */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; @@ -571,18 +450,15 @@ static void process_bus_reset(uint8_t rhport) /* When pipe0.buf has not NULL, DATA stage works in progress. */ _dcd.pipe0.buf = NULL; - USB0->TXIE = 1; /* Enable only EP0 */ - USB0->RXIE = 0; + ctrl_regs->TXIE = 1; /* Enable only EP0 */ + ctrl_regs->RXIE = 0; /* Clear FIFO settings */ for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - USB0->EPIDX = i; - USB0->TXFIFOSZ = 0; - USB0->TXFIFOADD = 0; - USB0->RXFIFOSZ = 0; - USB0->RXFIFOADD = 0; + musb_dcd_reset_fifo(rhport, i, 0); + musb_dcd_reset_fifo(rhport, i, 1); } - dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); + dcd_event_bus_reset(rhport, (ctrl_regs->POWER & USB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); } /*------------------------------------------------------------------ @@ -591,61 +467,60 @@ static void process_bus_reset(uint8_t rhport) void dcd_init(uint8_t rhport) { - (void)rhport; - USB0->IE |= USB_IE_SUSPND; - NVIC_ClearPendingIRQ(USB0_IRQn); - + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + ctrl_regs->IE |= USB_IE_SUSPND; + musb_dcd_int_clear(rhport); + musb_dcd_phy_init(rhport); dcd_connect(rhport); } void dcd_int_enable(uint8_t rhport) { - (void)rhport; - NVIC_EnableIRQ(USB0_IRQn); + musb_dcd_int_enable(rhport); } void dcd_int_disable(uint8_t rhport) { - (void)rhport; - NVIC_DisableIRQ(USB0_IRQn); + musb_dcd_int_disable(rhport); } // Receive Set Address request, mcu port must also include status IN response void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { - (void)rhport; (void)dev_addr; + volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO to return ACK. */ - USB0->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; + ep0_regs->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; } // Wake up host void dcd_remote_wakeup(uint8_t rhport) { - (void)rhport; - USB0->POWER |= USB_POWER_RESUME; + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + ctrl_regs->POWER |= USB_POWER_RESUME; unsigned cnt = SystemCoreClock / 1000; while (cnt--) __NOP(); - USB0->POWER &= ~USB_POWER_RESUME; + ctrl_regs->POWER &= ~USB_POWER_RESUME; } // Connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { - (void)rhport; - USB0->POWER |= USB_POWER_SOFTCONN; + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + ctrl_regs->POWER |= TUD_OPT_HIGH_SPEED ? USB_POWER_HSENAB : 0; + ctrl_regs->POWER |= USB_POWER_SOFTCONN; } // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { - (void)rhport; - USB0->POWER &= ~USB_POWER_SOFTCONN; + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + ctrl_regs->POWER &= ~USB_POWER_SOFTCONN; } void dcd_sof_enable(uint8_t rhport, bool en) @@ -663,8 +538,6 @@ void dcd_sof_enable(uint8_t rhport, bool en) // Configure endpoint's registers according to descriptor bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { - (void) rhport; - const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir_in = tu_edpt_dir(ep_addr); @@ -678,7 +551,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) pipe->length = 0; pipe->remaining = 0; - volatile hw_endpoint_t *regs = edpt_regs(epn - 1); + volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); if (dir_in) { regs->TXMAXP = mps; regs->TXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0; @@ -686,7 +560,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; else regs->TXCSRL = USB_TXCSRL1_CLRDT; - USB0->TXIE |= TU_BIT(epn); + ctrl_regs->TXIE |= TU_BIT(epn); } else { regs->RXMAXP = mps; regs->RXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; @@ -694,36 +568,25 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; else regs->RXCSRL = USB_RXCSRL1_CLRDT; - USB0->RXIE |= TU_BIT(epn); + ctrl_regs->RXIE |= TU_BIT(epn); } /* Setup FIFO */ - int size_in_log2_minus3 = 28 - TU_MIN(28, __CLZ((uint32_t)mps)); - if ((8u << size_in_log2_minus3) < mps) ++size_in_log2_minus3; - unsigned addr = find_free_memory(size_in_log2_minus3); - TU_ASSERT(addr); - - USB0->EPIDX = epn; - if (dir_in) { - USB0->TXFIFOADD = addr; - USB0->TXFIFOSZ = size_in_log2_minus3; - } else { - USB0->RXFIFOADD = addr; - USB0->RXFIFOSZ = size_in_log2_minus3; - } + musb_dcd_setup_fifo(rhport, epn, dir_in, mps); return true; } void dcd_edpt_close_all(uint8_t rhport) { - (void) rhport; - volatile hw_endpoint_t *regs = (volatile hw_endpoint_t *)(uintptr_t)&USB0->TXMAXP1; - unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); - NVIC_DisableIRQ(USB0_IRQn); - USB0->TXIE = 1; /* Enable only EP0 */ - USB0->RXIE = 0; + volatile musb_dcd_epn_regs_t *regs; + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); + ctrl_regs->TXIE = 1; /* Enable only EP0 */ + ctrl_regs->RXIE = 0; for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { + regs = musb_dcd_epn_regs(rhport, i); regs->TXMAXP = 0; regs->TXCSRH = 0; if (regs->TXCSRL & USB_TXCSRL1_TXRDY) @@ -738,50 +601,41 @@ void dcd_edpt_close_all(uint8_t rhport) else regs->RXCSRL = USB_RXCSRL1_CLRDT; - USB0->EPIDX = i; - USB0->TXFIFOSZ = 0; - USB0->TXFIFOADD = 0; - USB0->RXFIFOSZ = 0; - USB0->RXFIFOADD = 0; + musb_dcd_reset_fifo(rhport, i, 0); + musb_dcd_reset_fifo(rhport, i, 1); + } - if (ie) NVIC_EnableIRQ(USB0_IRQn); + if (ie) musb_dcd_int_enable(rhport); } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - (void)rhport; unsigned const epn = tu_edpt_number(ep_addr); unsigned const dir_in = tu_edpt_dir(ep_addr); - hw_endpoint_t volatile *regs = edpt_regs(epn - 1); - unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); - NVIC_DisableIRQ(USB0_IRQn); + volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); if (dir_in) { - USB0->TXIE &= ~TU_BIT(epn); + ctrl_regs->TXIE &= ~TU_BIT(epn); regs->TXMAXP = 0; regs->TXCSRH = 0; if (regs->TXCSRL & USB_TXCSRL1_TXRDY) regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; else regs->TXCSRL = USB_TXCSRL1_CLRDT; - - USB0->EPIDX = epn; - USB0->TXFIFOSZ = 0; - USB0->TXFIFOADD = 0; } else { - USB0->RXIE &= ~TU_BIT(epn); + ctrl_regs->RXIE &= ~TU_BIT(epn); regs->RXMAXP = 0; regs->RXCSRH = 0; if (regs->RXCSRL & USB_RXCSRL1_RXRDY) regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; else regs->RXCSRL = USB_RXCSRL1_CLRDT; - - USB0->EPIDX = epn; - USB0->RXFIFOSZ = 0; - USB0->RXFIFOADD = 0; } - if (ie) NVIC_EnableIRQ(USB0_IRQn); + musb_dcd_reset_fifo(rhport, epn, dir_in); + if (ie) musb_dcd_int_enable(rhport); } // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack @@ -791,14 +645,14 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t bool ret; // TU_LOG1("X %x %d\r\n", ep_addr, total_bytes); unsigned const epnum = tu_edpt_number(ep_addr); - unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); - NVIC_DisableIRQ(USB0_IRQn); + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); if (epnum) { _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); } else ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); - if (ie) NVIC_EnableIRQ(USB0_IRQn); + if (ie) musb_dcd_int_enable(rhport); return ret; } @@ -810,29 +664,29 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ // TU_LOG1("X %x %d\r\n", ep_addr, total_bytes); unsigned const epnum = tu_edpt_number(ep_addr); TU_ASSERT(epnum); - unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); - NVIC_DisableIRQ(USB0_IRQn); + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] |= TU_BIT(epnum - 1); ret = edpt_n_xfer(rhport, ep_addr, (uint8_t*)ff, total_bytes); - if (ie) NVIC_EnableIRQ(USB0_IRQn); + if (ie) musb_dcd_int_enable(rhport); return ret; } // Stall endpoint void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { - (void)rhport; unsigned const epn = tu_edpt_number(ep_addr); - unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); - NVIC_DisableIRQ(USB0_IRQn); + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); if (0 == epn) { + volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); if (!ep_addr) { /* Ignore EP80 */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.pipe0.buf = NULL; - USB0->CSRL0 = USB_CSRL0_STALL; + ep0_regs->CSRL0 = USB_CSRL0_STALL; } } else { - volatile hw_endpoint_t *regs = edpt_regs(epn - 1); + volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); if (tu_edpt_dir(ep_addr)) { /* IN */ regs->TXCSRL = USB_TXCSRL1_STALL; } else { /* OUT */ @@ -840,7 +694,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) regs->RXCSRL = USB_RXCSRL1_STALL; } } - if (ie) NVIC_EnableIRQ(USB0_IRQn); + if (ie) musb_dcd_int_enable(rhport); } // clear stall, data toggle is also reset to DATA0 @@ -848,15 +702,15 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; unsigned const epn = tu_edpt_number(ep_addr); - hw_endpoint_t volatile *regs = edpt_regs(epn - 1); - unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); - NVIC_DisableIRQ(USB0_IRQn); + musb_dcd_epn_regs_t volatile *regs = musb_dcd_epn_regs(rhport, epn); + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); if (tu_edpt_dir(ep_addr)) { /* IN */ regs->TXCSRL = USB_TXCSRL1_CLRDT; } else { /* OUT */ regs->RXCSRL = USB_RXCSRL1_CLRDT; } - if (ie) NVIC_EnableIRQ(USB0_IRQn); + if (ie) musb_dcd_int_enable(rhport); } /*------------------------------------------------------------------- @@ -865,13 +719,18 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) void dcd_int_handler(uint8_t rhport) { uint_fast8_t is, txis, rxis; + volatile musb_dcd_ctl_regs_t *ctrl_regs; + + //Part specific ISR setup/entry + musb_dcd_int_handler_enter(rhport); - is = USB0->IS; /* read and clear interrupt status */ - txis = USB0->TXIS; /* read and clear interrupt status */ - rxis = USB0->RXIS; /* read and clear interrupt status */ + ctrl_regs = musb_dcd_ctl_regs(rhport); + is = ctrl_regs->IS; /* read and clear interrupt status */ + txis = ctrl_regs->TXIS; /* read and clear interrupt status */ + rxis = ctrl_regs->RXIS; /* read and clear interrupt status */ // TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis); - is &= USB0->IE; /* Clear disabled interrupts */ + is &= ctrl_regs->IE; /* Clear disabled interrupts */ if (is & USB_IS_DISCON) { } if (is & USB_IS_SOF) { @@ -887,7 +746,7 @@ void dcd_int_handler(uint8_t rhport) dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } - txis &= USB0->TXIE; /* Clear disabled interrupts */ + txis &= ctrl_regs->TXIE; /* Clear disabled interrupts */ if (txis & USB_TXIE_EP0) { process_ep0(rhport); txis &= ~TU_BIT(0); @@ -897,12 +756,15 @@ void dcd_int_handler(uint8_t rhport) process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN)); txis &= ~TU_BIT(num); } - rxis &= USB0->RXIE; /* Clear disabled interrupts */ + rxis &= ctrl_regs->RXIE; /* Clear disabled interrupts */ while (rxis) { unsigned const num = __builtin_ctz(rxis); process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT)); rxis &= ~TU_BIT(num); } + + //Part specific ISR exit + musb_dcd_int_handler_exit(rhport); } #endif diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c index 5312c2812..8fc225676 100644 --- a/src/portable/mentor/musb/hcd_musb.c +++ b/src/portable/mentor/musb/hcd_musb.c @@ -37,16 +37,10 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); #include "host/hcd.h" -#if TU_CHECK_MCU(OPT_MCU_MSP432E4) - #include "musb_msp432e.h" - -#elif TU_CHECK_MCU(OPT_MCU_TM4C123, OPT_MCU_TM4C129) - #include "musb_tm4c.h" - - // HACK generalize later - #include "musb_type.h" - #define FIFO0_WORD FIFO0 +#include "musb_type.h" +#if TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) + #include "musb_ti.h" #else #error "Unsupported MCUs" #endif diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h new file mode 100644 index 000000000..297a695f8 --- /dev/null +++ b/src/portable/mentor/musb/musb_max32.h @@ -0,0 +1,221 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_MUSB_MAX32_H_ +#define _TUSB_MUSB_MAX32_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#if TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002) + #include "mxc_device.h" + #include "usbhs_regs.h" +#else + #error "Unsupported MCUs" +#endif + + +#if CFG_TUD_ENABLED +#define USBHS_M31_CLOCK_RECOVERY + +// Mapping of peripheral instances to port. Currently just 1. +static mxc_usbhs_regs_t* const musb_periph_inst[] = { + MXC_USBHS +}; + +// Mapping of IRQ numbers to port. Currently just 1. +static const IRQn_Type musb_irqs[] = { + USB_IRQn +}; + +TU_ATTR_ALWAYS_INLINE +static inline void musb_dcd_int_enable(uint8_t rhport) +{ + NVIC_EnableIRQ(musb_irqs[rhport]); +} + +TU_ATTR_ALWAYS_INLINE +static inline void musb_dcd_int_disable(uint8_t rhport) +{ + NVIC_DisableIRQ(musb_irqs[rhport]); +} + +TU_ATTR_ALWAYS_INLINE +static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) +{ + return NVIC_GetEnableIRQ(musb_irqs[rhport]); +} + +TU_ATTR_ALWAYS_INLINE +static inline void musb_dcd_int_clear(uint8_t rhport) +{ + NVIC_ClearPendingIRQ(musb_irqs[rhport]); +} + +//Used to save and restore user's register map when interrupt occurs +static volatile unsigned isr_saved_index = 0; + +static inline void musb_dcd_int_handler_enter(uint8_t rhport) +{ + uint32_t mxm_int, mxm_int_en, mxm_is; + + //save current register index + isr_saved_index = musb_periph_inst[rhport]->index; + + //Handle PHY specific events + mxm_int = musb_periph_inst[rhport]->mxm_int; + mxm_int_en = musb_periph_inst[rhport]->mxm_int_en; + mxm_is = mxm_int & mxm_int_en; + musb_periph_inst[rhport]->mxm_int = mxm_is; + + if (mxm_is & MXC_F_USBHS_MXM_INT_NOVBUS) { + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); + } +} + +static inline void musb_dcd_int_handler_exit(uint8_t rhport) +{ + //restore register index + musb_periph_inst[rhport]->index = isr_saved_index; +} + +static inline void musb_dcd_phy_init(uint8_t rhport) +{ + //Interrupt for VBUS disconnect + musb_periph_inst[rhport]->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS; + + musb_dcd_int_clear(rhport); + + //Unsuspend the MAC + musb_periph_inst[rhport]->mxm_suspend = 0; + + // Configure PHY + musb_periph_inst[rhport]->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11); + musb_periph_inst[rhport]->m31_phy_xcfgi_63_32 = 0; + musb_periph_inst[rhport]->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64); + musb_periph_inst[rhport]->m31_phy_xcfgi_127_96 = 0; + + + #ifdef USBHS_M31_CLOCK_RECOVERY + musb_periph_inst[rhport]->m31_phy_noncry_rstb = 1; + musb_periph_inst[rhport]->m31_phy_noncry_en = 1; + musb_periph_inst[rhport]->m31_phy_outclksel = 0; + musb_periph_inst[rhport]->m31_phy_coreclkin = 0; + musb_periph_inst[rhport]->m31_phy_xtlsel = 2; /* Select 25 MHz clock */ + #else + musb_periph_inst[rhport]->m31_phy_noncry_rstb = 0; + musb_periph_inst[rhport]->m31_phy_noncry_en = 0; + musb_periph_inst[rhport]->m31_phy_outclksel = 1; + musb_periph_inst[rhport]->m31_phy_coreclkin = 1; + musb_periph_inst[rhport]->m31_phy_xtlsel = 3; /* Select 30 MHz clock */ + #endif + musb_periph_inst[rhport]->m31_phy_pll_en = 1; + musb_periph_inst[rhport]->m31_phy_oscouten = 1; + + /* Reset PHY */ + musb_periph_inst[rhport]->m31_phy_ponrst = 0; + musb_periph_inst[rhport]->m31_phy_ponrst = 1; +} + +static inline volatile musb_dcd_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) +{ + volatile musb_dcd_ctl_regs_t *regs = (volatile musb_dcd_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->faddr)); + return regs; +} + +static inline volatile musb_dcd_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) +{ + //Need to set index to map EP registers + musb_periph_inst[rhport]->index = epnum; + volatile musb_dcd_epn_regs_t *regs = (volatile musb_dcd_epn_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->inmaxp)); + return regs; +} + +static inline volatile musb_dcd_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) +{ + //Need to set index to map EP0 registers + musb_periph_inst[rhport]->index = 0; + volatile musb_dcd_ep0_regs_t *regs = (volatile musb_dcd_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->csr0)); + return regs; +} + +static volatile void *musb_dcd_ep_get_fifo_ptr(uint8_t rhport, unsigned epnum) +{ + volatile uint32_t *ptr; + + ptr = &(musb_periph_inst[rhport]->fifo0); + ptr += epnum; + + return (volatile void *) ptr; +} + + +static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) +{ + (void)mps; + + //Most likely the caller has already grabbed the right register block. But + //as a precaution save and restore the register bank anyways + unsigned saved_index = musb_periph_inst[rhport]->index; + + musb_periph_inst[rhport]->index = epnum; + + //Disable double buffering + if(dir_in) { + musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE); + } else { + musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); + } + + musb_periph_inst[rhport]->index = saved_index; +} + +static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in) +{ + //Most likely the caller has already grabbed the right register block. But + //as a precaution save and restore the register bank anyways + unsigned saved_index = musb_periph_inst[rhport]->index; + + musb_periph_inst[rhport]->index = epnum; + + //Disable double buffering + if(dir_in) { + musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS); + } else { + musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); + } + + musb_periph_inst[rhport]->index = saved_index; +} + +#endif // CFG_TUD_ENABLED + +#ifdef __cplusplus + } +#endif + +#endif // _TUSB_MUSB_MAX32_H_ diff --git a/src/portable/mentor/musb/musb_msp432e.h b/src/portable/mentor/musb/musb_msp432e.h deleted file mode 100644 index fce21de88..000000000 --- a/src/portable/mentor/musb/musb_msp432e.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2021, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef _TUSB_MUSB_MSP432E_H_ -#define _TUSB_MUSB_MSP432E_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#include "msp.h" - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h new file mode 100644 index 000000000..dbf82f391 --- /dev/null +++ b/src/portable/mentor/musb/musb_ti.h @@ -0,0 +1,285 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_MUSB_TI_H_ +#define _TUSB_MUSB_TI_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#if CFG_TUSB_MCU == OPT_MCU_TM4C123 + #include "TM4C123.h" + #define FIFO0_WORD FIFO0 + #define FIFO1_WORD FIFO1 +//#elif CFG_TUSB_MCU == OPT_MCU_TM4C129 +#elif CFG_TUSB_MCU == OPT_MCU_MSP432E4 + #include "msp.h" +#else + #error "Unsupported MCUs" +#endif + + +// Header supports both device and host modes. Only include whats necessary +#if CFG_TUD_ENABLED + +// Mapping of peripheral instances to port. Currently just 1. +static USB0_Type* const musb_periph_inst[] = { + USB0 +}; + +// Mapping of IRQ numbers to port. Currently just 1. +static const IRQn_Type musb_irqs[] = { + USB0_IRQn +}; + +static inline void musb_dcd_phy_init(uint8_t rhport){ + (void)rhport; + //Nothing to do for this part +} + +TU_ATTR_ALWAYS_INLINE +static inline void musb_dcd_int_enable(uint8_t rhport) +{ + NVIC_EnableIRQ(musb_irqs[rhport]); +} + +TU_ATTR_ALWAYS_INLINE +static inline void musb_dcd_int_disable(uint8_t rhport) +{ + NVIC_DisableIRQ(musb_irqs[rhport]); +} + +TU_ATTR_ALWAYS_INLINE +static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) +{ + return NVIC_GetEnableIRQ(musb_irqs[rhport]); +} + +TU_ATTR_ALWAYS_INLINE +static inline void musb_dcd_int_clear(uint8_t rhport) +{ + NVIC_ClearPendingIRQ(musb_irqs[rhport]); +} + +static inline void musb_dcd_int_handler_enter(uint8_t rhport){ + (void)rhport; + //Nothing to do for this part +} + +static inline void musb_dcd_int_handler_exit(uint8_t rhport){ + (void)rhport; + //Nothing to do for this part +} + +static inline volatile musb_dcd_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) +{ + volatile musb_dcd_ctl_regs_t *regs = (volatile musb_dcd_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->FADDR)); + return regs; +} + +static inline volatile musb_dcd_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) +{ + uintptr_t baseptr = (uintptr_t)&(musb_periph_inst[rhport]->TXMAXP1); + + //On the TI parts, the epn registers are 16-bytes apart. The core regs defined + //by musb_dcd_epn_regs and 6 reserved/other use bytes + volatile musb_dcd_epn_regs_t *regs = (volatile musb_dcd_epn_regs_t*)(baseptr + ((epnum - 1)*16)); + return regs; +} + +static inline volatile musb_dcd_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) +{ + volatile musb_dcd_ep0_regs_t *regs = (volatile musb_dcd_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->CSRL0)); + return regs; +} + +static volatile void *musb_dcd_ep_get_fifo_ptr(uint8_t rhport, unsigned epnum) +{ + if(epnum){ + return (volatile void *)(&(musb_periph_inst[rhport]->FIFO1_WORD) + (epnum - 1)); + } else { + return (volatile void *)&(musb_periph_inst[rhport]->FIFO0_WORD); + } +} + + +typedef struct { + uint_fast16_t beg; /* offset of including first element */ + uint_fast16_t end; /* offset of excluding the last element */ +} free_block_t; + +static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) +{ + free_block_t *cur = beg; + for (; cur < end && ((addr < cur->beg) || (cur->end <= addr)); ++cur) ; + return cur; +} + +static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) +{ + free_block_t *p = find_containing_block(blks, blks + num, addr); + TU_ASSERT(p != blks + num, -2); + if (p->beg == addr) { + /* Shrink block */ + p->beg = addr + size; + if (p->beg != p->end) return 0; + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } else { + /* Split into 2 blocks */ + free_block_t tmp = { + .beg = addr + size, + .end = p->end + }; + p->end = addr; + if (p->beg == p->end) { + if (tmp.beg != tmp.end) { + *p = tmp; + return 0; + } + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } + if (tmp.beg == tmp.end) return 0; + blks[num] = tmp; + return 1; + } +} + +static inline unsigned free_block_size(free_block_t const *blk) +{ + return blk->end - blk->beg; +} + +#if 0 +static inline void print_block_list(free_block_t const *blk, unsigned num) +{ + TU_LOG1("*************\r\n"); + for (unsigned i = 0; i < num; ++i) { + TU_LOG1(" Blk%u %u %u\r\n", i, blk->beg, blk->end); + ++blk; + } +} +#else +#define print_block_list(a,b) +#endif + +static unsigned find_free_memory(uint8_t rhport, uint_fast16_t size_in_log2_minus3) +{ + free_block_t free_blocks[2 * (TUP_DCD_ENDPOINT_MAX - 1)]; + unsigned num_blocks = 1; + + /* Initialize free memory block list */ + free_blocks[0].beg = 64 / 8; + free_blocks[0].end = (4 << 10) / 8; /* 4KiB / 8 bytes */ + for (int i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { + uint_fast16_t addr; + int num; + musb_periph_inst[rhport]->EPIDX = i; + addr = musb_periph_inst[rhport]->TXFIFOADD; + if (addr) { + unsigned sz = musb_periph_inst[rhport]->TXFIFOSZ; + unsigned sft = (sz & USB_TXFIFOSZ_SIZE_M) + ((sz & USB_TXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + print_block_list(free_blocks, num_blocks); + } + addr = musb_periph_inst[rhport]->RXFIFOADD; + if (addr) { + unsigned sz = musb_periph_inst[rhport]->RXFIFOSZ; + unsigned sft = (sz & USB_RXFIFOSZ_SIZE_M) + ((sz & USB_RXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + print_block_list(free_blocks, num_blocks); + } + } + print_block_list(free_blocks, num_blocks); + + /* Find the best fit memory block */ + uint_fast16_t size_in_8byte_unit = 1 << size_in_log2_minus3; + free_block_t const *min = NULL; + uint_fast16_t min_sz = 0xFFFFu; + free_block_t const *end = &free_blocks[num_blocks]; + for (free_block_t const *cur = &free_blocks[0]; cur < end; ++cur) { + uint_fast16_t sz = free_block_size(cur); + if (sz < size_in_8byte_unit) continue; + if (size_in_8byte_unit == sz) return cur->beg; + if (sz < min_sz) min = cur; + } + TU_ASSERT(min, 0); + return min->beg; +} + + +static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) +{ + int size_in_log2_minus3 = 28 - TU_MIN(28, __CLZ((uint32_t)mps)); + if ((8u << size_in_log2_minus3) < mps) ++size_in_log2_minus3; + unsigned addr = find_free_memory(rhport, size_in_log2_minus3); + TU_ASSERT(addr,); + + musb_periph_inst[rhport]->EPIDX = epnum; + if (dir_in) { + musb_periph_inst[rhport]->TXFIFOADD = addr; + musb_periph_inst[rhport]->TXFIFOSZ = size_in_log2_minus3; + } else { + musb_periph_inst[rhport]->RXFIFOADD = addr; + musb_periph_inst[rhport]->RXFIFOSZ = size_in_log2_minus3; + } +} + +static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in) +{ + musb_periph_inst[rhport]->EPIDX = epnum; + if (dir_in) { + musb_periph_inst[rhport]->TXFIFOADD = 0; + musb_periph_inst[rhport]->TXFIFOSZ = 0; + } else { + musb_periph_inst[rhport]->RXFIFOADD = 0; + musb_periph_inst[rhport]->RXFIFOSZ = 0; + } +} + +#endif // CFG_TUD_ENABLED + +#ifdef __cplusplus + } +#endif + +#endif // _TUSB_MUSB_TI_H_ diff --git a/src/portable/mentor/musb/musb_tm4c.h b/src/portable/mentor/musb/musb_tm4c.h deleted file mode 100644 index 65a1751b0..000000000 --- a/src/portable/mentor/musb/musb_tm4c.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2021, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef _TUSB_MUSB_TM4C_H_ -#define _TUSB_MUSB_TM4C_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#if CFG_TUSB_MCU == OPT_MCU_TM4C123 - #include "TM4C123.h" -//#elif CFG_TUSB_MCU == OPT_MCU_TM4C129 -#else - #error "Unsupported MCUs" -#endif - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 8f83305a5..e8af8f19b 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -35,10 +35,43 @@ #ifndef _TUSB_MUSB_TYPE_H_ #define _TUSB_MUSB_TYPE_H_ +#include "stdint.h" + #ifdef __cplusplus extern "C" { #endif +// Endpoint register mapping. Non-zero end points. +typedef struct TU_ATTR_PACKED { + uint16_t TXMAXP; + uint8_t TXCSRL; + uint8_t TXCSRH; + uint16_t RXMAXP; + uint8_t RXCSRL; + uint8_t RXCSRH; + uint16_t RXCOUNT; +} musb_dcd_epn_regs_t; + +// Endpoint 0 register mapping. +typedef struct TU_ATTR_PACKED { + uint8_t CSRL0; + uint8_t CSRH0; + uint32_t RESERVED; + uint8_t COUNT0; +} musb_dcd_ep0_regs_t; + +// Control register mapping +typedef struct TU_ATTR_PACKED { + uint8_t FADDR; + uint8_t POWER; + uint16_t TXIS; + uint16_t RXIS; + uint16_t TXIE; + uint16_t RXIE; + uint8_t IS; + uint8_t IE; +} musb_dcd_ctl_regs_t; + //***************************************************************************** // // The following are defines for the bit fields in the USB_O_FADDR register. -- cgit v1.3.1 From ef4285c00c1561a106b99dd0572cef11f5448919 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Jul 2024 22:38:23 +0700 Subject: add flash stlink --- test/hil/hil_test.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 158841687..e2a2f01a0 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -137,6 +137,11 @@ def flash_jlink(board, firmware): return ret +def flash_stlink(board, firmware): + #ret = run_cmd(f'st-flash --serial {board["flasher_sn"]} write {firmware}.bin 0x08000000') + ret = run_cmd(f'STM32_Programmer_CLI --connect port=swd sn={board["flasher_sn"]} --write {firmware}.elf --go') + return ret + def flash_openocd(board, firmware): ret = run_cmd(f'openocd -c "adapter serial {board["flasher_sn"]}" {board["flasher_args"]} -c "program {firmware}.elf reset exit"') return ret @@ -338,8 +343,10 @@ def main(): # all possible tests: board_test is added last to disable board's usb all_tests = [ 'cdc_dual_ports', - 'cdc_msc', 'cdc_msc_freertos', - 'dfu', 'dfu_runtime', + 'cdc_msc', + 'cdc_msc_freertos', + 'dfu', + 'dfu_runtime', 'hid_boot_interface', 'board_test' ] -- cgit v1.3.1 From 3b8f9a2b1f43a8353c1556e30a61dd0c2416c57f Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Jul 2024 23:51:20 +0700 Subject: refactor btable tx/rx into arr[2] --- src/portable/st/stm32_fsdev/fsdev_common.h | 95 ++++++++++++++++-------------- 1 file changed, 51 insertions(+), 44 deletions(-) diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index d0f928552..7d1f7fd90 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -69,17 +69,18 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b // 16-bit or 32-bit depending on FSDEV_BUS_32BIT. typedef struct { union { + // 0: tx, 1: rx + + // strictly 16-bit access (could be 32-bit aligned) struct { - volatile pma_aligned uint16_t tx_addr; - volatile pma_aligned uint16_t tx_count; - volatile pma_aligned uint16_t rx_addr; - volatile pma_aligned uint16_t rx_count; - } ep16[FSDEV_EP_COUNT]; + volatile pma_aligned uint16_t addr; + volatile pma_aligned uint16_t count; + } ep16[FSDEV_EP_COUNT][2]; + // strictly 32-bit access struct { - volatile uint32_t tx_count_addr; - volatile uint32_t rx_count_addr; - } ep32[FSDEV_EP_COUNT]; + volatile uint32_t count_addr; + } ep32[FSDEV_EP_COUNT][2]; }; } fsdev_btable_t; @@ -204,6 +205,24 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, pcd_set_endpoint(USBx, bEpIdx,regVal); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t is_rx) { + uint16_t count; +#ifdef FSDEV_BUS_32BIT + count = (FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr >> 16); +#else + count = FSDEV_BTABLE->ep16[ep_id][is_rx].count; +#endif + return count & 0x3FFU; +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t is_rx) { +#ifdef FSDEV_BUS_32BIT + return FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr & 0x0000FFFFu; +#else + return FSDEV_BTABLE->ep16[ep_id][is_rx].addr; +#endif +} + /** * @brief gets counter of the tx buffer. * @param USBx USB peripheral instance register address. @@ -212,26 +231,12 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, */ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { (void) USBx; - uint16_t count; -#ifdef FSDEV_BUS_32BIT - count = (FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr >> 16); -#else - count = FSDEV_BTABLE->ep16[bEpIdx].tx_count; -#endif - - return count & 0x3FFU; + return btable_get_count(bEpIdx, 0); } TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { (void) USBx; - uint16_t count; -#ifdef FSDEV_BUS_32BIT - count = (FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr >> 16); -#else - count = FSDEV_BTABLE->ep16[bEpIdx].rx_count; -#endif - - return count & 0x3FFU; + return btable_get_count(bEpIdx, 1); } #define pcd_get_ep_dbuf0_cnt pcd_get_ep_tx_cnt @@ -239,44 +244,46 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USB TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { (void) USBx; -#ifdef FSDEV_BUS_32BIT - return FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr & 0x0000FFFFu; -#else - return FSDEV_BTABLE->ep16[bEpIdx].tx_addr; -#endif + return btable_get_addr(bEpIdx, 0); } TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { (void) USBx; -#ifdef FSDEV_BUS_32BIT - return FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr & 0x0000FFFFu; -#else - return FSDEV_BTABLE->ep16[bEpIdx].rx_addr; -#endif + return btable_get_addr(bEpIdx, 1); } #define pcd_get_ep_dbuf0_address pcd_get_ep_tx_address #define pcd_get_ep_dbuf1_address pcd_get_ep_rx_address + +//TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_set_addr(uint32_t ep_id, uint8_t is_rx, uint16_t addr) { +// +//} +// +//TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_set_count(uint32_t ep_id, uint8_t is_rx, uint16_t count) { +// +//} + + TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { (void) USBx; #ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr; + uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx][0].count_addr; count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); - FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr = count_addr; + FSDEV_BTABLE->ep32[bEpIdx][0].count_addr = count_addr; #else - FSDEV_BTABLE->ep16[bEpIdx].tx_addr = addr; + FSDEV_BTABLE->ep16[bEpIdx][0].addr = addr; #endif } TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { (void) USBx; #ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr; + uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx][1].count_addr; count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); - FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr = count_addr; + FSDEV_BTABLE->ep32[bEpIdx][1].count_addr = count_addr; #else - FSDEV_BTABLE->ep16[bEpIdx].rx_addr = addr; + FSDEV_BTABLE->ep16[bEpIdx][1].addr = addr; #endif } @@ -286,13 +293,13 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USB TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { (void) USBx; #ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr; + uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx][0].count_addr; count_addr = (count_addr & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); - FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr = count_addr; + FSDEV_BTABLE->ep32[bEpIdx][0].count_addr = count_addr; #else - uint16_t count = FSDEV_BTABLE->ep16[bEpIdx].tx_count; + uint16_t count = FSDEV_BTABLE->ep16[bEpIdx][0].count; count = (count & ~0x3FFU) | (wCount & 0x3FFU); - FSDEV_BTABLE->ep16[bEpIdx].tx_count = count; + FSDEV_BTABLE->ep16[bEpIdx][0].count = count; #endif } -- cgit v1.3.1 From 75d3a3be84fa50abd5519e1879aa5dafc4a5c37d Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 26 Jul 2024 00:02:06 +0700 Subject: implement btable_set_addr/count --- src/portable/st/stm32_fsdev/fsdev_common.h | 51 +++++++++++++----------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 7d1f7fd90..58a9ed96d 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -256,51 +256,44 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * #define pcd_get_ep_dbuf1_address pcd_get_ep_rx_address -//TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_set_addr(uint32_t ep_id, uint8_t is_rx, uint16_t addr) { -// -//} -// -//TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_set_count(uint32_t ep_id, uint8_t is_rx, uint16_t count) { -// -//} - - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { - (void) USBx; +TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t is_rx, uint16_t addr) { #ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx][0].count_addr; + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr; count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); - FSDEV_BTABLE->ep32[bEpIdx][0].count_addr = count_addr; + FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr = count_addr; #else - FSDEV_BTABLE->ep16[bEpIdx][0].addr = addr; + FSDEV_BTABLE->ep16[ep_id][is_rx].addr = addr; #endif } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { - (void) USBx; +TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t is_rx, uint16_t byte_count) { #ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx][1].count_addr; - count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); - FSDEV_BTABLE->ep32[bEpIdx][1].count_addr = count_addr; + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr; + count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16); + FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr = count_addr; #else - FSDEV_BTABLE->ep16[bEpIdx][1].addr = addr; + uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][is_rx].count; + cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU); + FSDEV_BTABLE->ep16[ep_id][is_rx].count = cnt; #endif } +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { + (void) USBx; + btable_set_addr(bEpIdx, 0, addr); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { + (void) USBx; + btable_set_addr(bEpIdx, 1, addr); +} + #define pcd_set_ep_dbuf0_address pcd_set_ep_tx_address #define pcd_set_ep_dbuf1_address pcd_set_ep_rx_address TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { (void) USBx; -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx][0].count_addr; - count_addr = (count_addr & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); - FSDEV_BTABLE->ep32[bEpIdx][0].count_addr = count_addr; -#else - uint16_t count = FSDEV_BTABLE->ep16[bEpIdx][0].count; - count = (count & ~0x3FFU) | (wCount & 0x3FFU); - FSDEV_BTABLE->ep16[bEpIdx][0].count = count; -#endif + btable_set_count(bEpIdx, 0, wCount); } #define pcd_set_ep_tx_dbuf0_cnt pcd_set_ep_tx_cnt -- cgit v1.3.1 From 4a48544aebf362e77095c52ddcfcde6a65876acf Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 28 Jul 2024 12:04:25 +0200 Subject: audiod_function_t clean up. --- src/class/audio/audio_device.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 75bb0b883..8c86de433 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -303,8 +303,6 @@ typedef struct bool mounted; // Device opened - /*------------- From this point, data is not cleared by bus reset -------------*/ - uint16_t desc_length; // Length of audio function descriptor #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP @@ -369,6 +367,8 @@ typedef struct #endif #endif + /*------------- From this point, data is not cleared by bus reset -------------*/ + // Buffer for control requests uint8_t * ctrl_buf; uint8_t ctrl_buf_sz; @@ -377,14 +377,10 @@ typedef struct uint8_t * alt_setting; // We need to save the current alternate setting this way, because it is possible that there are AS interfaces which do not have an EP! // EP Transfer buffers and FIFOs -#if CFG_TUD_AUDIO_ENABLE_EP_OUT -#if !CFG_TUD_AUDIO_ENABLE_DECODING +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_AUDIO_ENABLE_DECODING tu_fifo_t ep_out_ff; #endif - -#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT - #if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING tu_fifo_t ep_in_ff; #endif @@ -394,7 +390,6 @@ typedef struct CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf[6]; #endif - // Support FIFOs for software encoding and decoding #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING tu_fifo_t * rx_supp_ff; -- cgit v1.3.1 From 6a67bac47c0f83eebd63ca99654ed26e51b21145 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 28 Jul 2024 13:23:48 +0200 Subject: Integrate OS guessing quirk into uac2_speaker_fb example. --- examples/device/uac2_speaker_fb/src/main.c | 16 ++++ .../device/uac2_speaker_fb/src/quirk_os_guessing.c | 90 ++++++++++++++++++++++ .../device/uac2_speaker_fb/src/quirk_os_guessing.h | 75 ++++++++++++++++++ examples/device/uac2_speaker_fb/src/tusb_config.h | 8 ++ .../device/uac2_speaker_fb/src/usb_descriptors.c | 67 +++++++++++++++- 5 files changed, 253 insertions(+), 3 deletions(-) create mode 100644 examples/device/uac2_speaker_fb/src/quirk_os_guessing.c create mode 100644 examples/device/uac2_speaker_fb/src/quirk_os_guessing.h diff --git a/examples/device/uac2_speaker_fb/src/main.c b/examples/device/uac2_speaker_fb/src/main.c index 8573dfa4c..0a8529a61 100644 --- a/examples/device/uac2_speaker_fb/src/main.c +++ b/examples/device/uac2_speaker_fb/src/main.c @@ -31,6 +31,10 @@ #include "usb_descriptors.h" #include "common_types.h" +#ifdef CFG_QUIRK_OS_GUESSING +#include "quirk_os_guessing.h" +#endif + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ @@ -385,6 +389,18 @@ bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_bytes_received, u return true; } #endif + +#if CFG_QUIRK_OS_GUESSING +bool tud_audio_feedback_format_correction_cb(uint8_t func_id) +{ + (void)func_id; + if(tud_speed_get() == TUSB_SPEED_FULL && quirk_os_guessing_get() == QUIRK_OS_GUESSING_OSX) { + return true; + } else { + return false; + } +} +#endif //--------------------------------------------------------------------+ // AUDIO Task //--------------------------------------------------------------------+ diff --git a/examples/device/uac2_speaker_fb/src/quirk_os_guessing.c b/examples/device/uac2_speaker_fb/src/quirk_os_guessing.c new file mode 100644 index 000000000..965bbd6cf --- /dev/null +++ b/examples/device/uac2_speaker_fb/src/quirk_os_guessing.c @@ -0,0 +1,90 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 HiFiPhile + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "quirk_os_guessing.h" + +static tusb_desc_type_t desc_req_buf[2]; +static int desc_req_idx = 0; + +// Place at the start of tud_descriptor_device_cb() +void quirk_os_guessing_desc_device_cb() { + desc_req_idx = 0; +} + +// Place at the start of tud_descriptor_configuration_cb() +void quirk_os_guessing_desc_configuration_cb() { + // Skip redundant request + if (desc_req_idx == 0 || (desc_req_idx == 1 && desc_req_buf[0] != TUSB_DESC_CONFIGURATION)) { + desc_req_buf[desc_req_idx++] = TUSB_DESC_CONFIGURATION; + } +} + +// Place at the start of tud_descriptor_bos_cb() +void quirk_os_guessing_desc_bos_cb() { + // Skip redundant request + if (desc_req_idx == 0 || (desc_req_idx == 1 && desc_req_buf[0] != TUSB_DESC_BOS)) { + desc_req_buf[desc_req_idx++] = TUSB_DESC_BOS; + } +} + +// Place at the start of tud_descriptor_string_cb() +void quirk_os_guessing_desc_string_cb() { + // Skip redundant request + if (desc_req_idx == 0 || (desc_req_idx == 1 && desc_req_buf[0] != TUSB_DESC_STRING)) { + desc_req_buf[desc_req_idx++] = TUSB_DESC_STRING; + } +} + +// Each OS request descriptors differently: +// Windows 10 - 11 +// Device Desc +// Config Desc +// BOS Desc +// String Desc +// Linux 3.16 - 6.8 +// Device Desc +// BOS Desc +// Config Desc +// String Desc +// OS X Ventura - Sonoma +// Device Desc +// String Desc +// Config Desc || BOS Desc +// BOS Desc || Config Desc +quirk_os_guessing_t quirk_os_guessing_get(void) { + if (desc_req_idx < 2) { + return QUIRK_OS_GUESSING_UNKNOWN; + } + + if (desc_req_buf[0] == TUSB_DESC_BOS && desc_req_buf[1] == TUSB_DESC_CONFIGURATION) { + return QUIRK_OS_GUESSING_LINUX; + } else if (desc_req_buf[0] == TUSB_DESC_CONFIGURATION && desc_req_buf[1] == TUSB_DESC_BOS) { + return QUIRK_OS_GUESSING_WINDOWS; + } else if (desc_req_buf[0] == TUSB_DESC_STRING && (desc_req_buf[1] == TUSB_DESC_BOS || desc_req_buf[1] == TUSB_DESC_CONFIGURATION)) { + return QUIRK_OS_GUESSING_OSX; + } + + return QUIRK_OS_GUESSING_UNKNOWN; +} diff --git a/examples/device/uac2_speaker_fb/src/quirk_os_guessing.h b/examples/device/uac2_speaker_fb/src/quirk_os_guessing.h new file mode 100644 index 000000000..1120355c9 --- /dev/null +++ b/examples/device/uac2_speaker_fb/src/quirk_os_guessing.h @@ -0,0 +1,75 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 HiFiPhile + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _QUIRK_OS_GUESSING_H_ +#define _QUIRK_OS_GUESSING_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "tusb.h" + +//================================== !!! WARNING !!! ==================================== +// This quirk operate out of USB specification in order to workaround specific issues. +// It may not work on your platform. +//======================================================================================= +// +// Prerequisites: +// - Set USB version to at least 2.01 in Device Descriptor +// - Has a valid BOS Descriptor, refer to webusb_serial example +// +// Attention: +// Windows detection result comes out after Configuration Descriptor request, +// meaning it will be too late to do descriptor adjustment. It's advised to make +// Windows as default configuration and adjust to other OS accordingly. + +typedef enum { + QUIRK_OS_GUESSING_UNKNOWN, + QUIRK_OS_GUESSING_LINUX, + QUIRK_OS_GUESSING_OSX, + QUIRK_OS_GUESSING_WINDOWS, +} quirk_os_guessing_t; + +// Get Host OS type +quirk_os_guessing_t quirk_os_guessing_get(void); + +// Place at the start of tud_descriptor_device_cb() +void quirk_os_guessing_desc_device_cb(void); + +// Place at the start of tud_descriptor_configuration_cb() +void quirk_os_guessing_desc_configuration_cb(void); + +// Place at the start of tud_descriptor_bos_cb() +void quirk_os_guessing_desc_bos_cb(void); + +// Place at the start of tud_descriptor_string_cb() +void quirk_os_guessing_desc_string_cb(void); + +#ifdef __cplusplus + } +#endif + +#endif /* _QUIRK_OS_GUESSING_H_ */ diff --git a/examples/device/uac2_speaker_fb/src/tusb_config.h b/examples/device/uac2_speaker_fb/src/tusb_config.h index 1cc1031c1..fd4925c7f 100644 --- a/examples/device/uac2_speaker_fb/src/tusb_config.h +++ b/examples/device/uac2_speaker_fb/src/tusb_config.h @@ -87,6 +87,14 @@ extern "C" { #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif +/* (Needed for Full-Speed only) + * Enable host OS guessing to workaround UAC2 compatibility issues between Windows and OS X + * The default configuration only support Windows and Linux, enable this option for OS X + * support. Otherwise if you don't need Windows support you can make OS X's configuration as + * default. + */ +#define CFG_QUIRK_OS_GUESSING 1 + //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- diff --git a/examples/device/uac2_speaker_fb/src/usb_descriptors.c b/examples/device/uac2_speaker_fb/src/usb_descriptors.c index fa307674d..31c5e116d 100644 --- a/examples/device/uac2_speaker_fb/src/usb_descriptors.c +++ b/examples/device/uac2_speaker_fb/src/usb_descriptors.c @@ -28,6 +28,10 @@ #include "usb_descriptors.h" #include "common_types.h" +#ifdef CFG_QUIRK_OS_GUESSING +#include "quirk_os_guessing.h" +#endif + /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * @@ -45,7 +49,7 @@ tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = 0x0200, + .bcdUSB = 0x0201, // Use Interface Association Descriptor (IAD) for Audio // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) @@ -69,6 +73,9 @@ tusb_desc_device_t const desc_device = // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { +#if CFG_QUIRK_OS_GUESSING + quirk_os_guessing_desc_device_cb(); +#endif return (uint8_t const *)&desc_device; } @@ -144,7 +151,7 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf) #define EPNUM_DEBUG 0x02 #endif -uint8_t const desc_configuration[] = +uint8_t const desc_configuration_default[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), @@ -158,13 +165,63 @@ uint8_t const desc_configuration[] = #endif }; +#if CFG_QUIRK_OS_GUESSING +// OS X needs 3 bytes feedback endpoint on FS +uint8_t const desc_configuration_osx_fs[] = +{ + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + + // Interface number, string index, byte per sample, bit per sample, EP Out, EP size, EP feedback, feedback EP size, + TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR(0, 4, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX, EPNUM_AUDIO_OUT, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX, EPNUM_AUDIO_FB | 0x80, 3), + +#if CFG_AUDIO_DEBUG + // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval + TUD_HID_DESCRIPTOR(ITF_NUM_DEBUG, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_DEBUG | 0x80, CFG_TUD_HID_EP_BUFSIZE, 7) +#endif +}; +#endif + // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void)index; // for multiple configurations - return desc_configuration; + +#if CFG_QUIRK_OS_GUESSING + quirk_os_guessing_desc_configuration_cb(); + if(tud_speed_get() == TUSB_SPEED_FULL && quirk_os_guessing_get() == QUIRK_OS_GUESSING_OSX) { + return desc_configuration_osx_fs; + } +#endif + return desc_configuration_default; +} + +//--------------------------------------------------------------------+ +// BOS Descriptor, required for OS guessing quirk +//--------------------------------------------------------------------+ + +#define TUD_BOS_USB20_EXT_DESC_LEN 7 + +#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_USB20_EXT_DESC_LEN) + +// BOS Descriptor is required for webUSB +uint8_t const desc_bos[] = +{ + // total length, number of device caps + TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 1), + + // USB 2.0 Extension Descriptor + 0x07, TUSB_DESC_DEVICE_CAPABILITY, DEVICE_CAPABILITY_USB20_EXTENSION, 0x00, 0x00, 0x00,0x00 +}; + +uint8_t const * tud_descriptor_bos_cb(void) +{ +#if CFG_QUIRK_OS_GUESSING + quirk_os_guessing_desc_bos_cb(); +#endif + return desc_bos; } //--------------------------------------------------------------------+ @@ -197,6 +254,10 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; +#if CFG_QUIRK_OS_GUESSING + quirk_os_guessing_desc_string_cb(); +#endif + switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); -- cgit v1.3.1 From cfb44a38926ec2e406dc6b91e90d601324b719d7 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Mon, 29 Jul 2024 12:28:58 -0500 Subject: add clocks.h as set_sys_clock_khz is moving there from stdlib.h --- hw/bsp/rp2040/family.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index cffb632f3..9360f7f57 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -31,6 +31,7 @@ #include "hardware/gpio.h" #include "hardware/sync.h" #include "hardware/resets.h" +#include "hardware/clocks.h" #include "hardware/structs/ioqspi.h" #include "hardware/structs/sio.h" -- cgit v1.3.1 From 0ebe81f4c3a6b38aef82b9f3a7d7f74fbf99c831 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Mon, 29 Jul 2024 12:34:25 -0500 Subject: add explcit dependency --- hw/bsp/rp2040/family.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index c81390b28..d91821ffa 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -133,7 +133,10 @@ target_sources(tinyusb_bsp INTERFACE target_include_directories(tinyusb_bsp INTERFACE ${TOP}/hw ) -target_link_libraries(tinyusb_bsp INTERFACE pico_unique_id) +target_link_libraries(tinyusb_bsp INTERFACE + pico_unique_id + hardware_clocks + ) # tinyusb_additions will hold our extra settings for examples add_library(tinyusb_additions INTERFACE) -- cgit v1.3.1 From 6771ef35d9fd61bcddb305dedef7d9f4addf86a5 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Jul 2024 11:17:55 +0700 Subject: more btable set/get clean up --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 54 +++++++++------------------ src/portable/st/stm32_fsdev/fsdev_common.h | 24 +----------- 2 files changed, 19 insertions(+), 59 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 927ecac85..fc1627a1c 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -320,12 +320,8 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) { return; } xfer->iso_in_sending = false; - - if (wEPRegVal & USB_EP_DTOG_TX) { - pcd_set_ep_tx_dbuf0_cnt(USB, EPindex, 0); - } else { - pcd_set_ep_tx_dbuf1_cnt(USB, EPindex, 0); - } + uint8_t buf_id = (wEPRegVal & USB_EP_DTOG_TX) ? 0 : 1; + btable_set_count(EPindex, buf_id, 0); } if ((xfer->total_len != xfer->queued_len)) { @@ -406,21 +402,16 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) if (ep_addr != 0u) { pcd_clear_rx_ep_ctr(USB, EPindex); } - uint32_t count; - uint16_t addr; - /* Read from correct register when ISOCHRONOUS (double buffered) */ + + uint8_t buf_id; if ((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { - if (wEPRegVal & USB_EP_DTOG_RX) { - count = pcd_get_ep_dbuf0_cnt(USB, EPindex); - addr = pcd_get_ep_dbuf0_address(USB, EPindex); - } else { - count = pcd_get_ep_dbuf1_cnt(USB, EPindex); - addr = pcd_get_ep_dbuf1_address(USB, EPindex); - } + // ISO endpoints are double buffered + buf_id = (wEPRegVal & USB_EP_DTOG_RX) ? 0 : 1; } else { - count = pcd_get_ep_rx_cnt(USB, EPindex); - addr = pcd_get_ep_rx_address(USB, EPindex); + buf_id = 1; } + uint32_t count = btable_get_count(EPindex, buf_id); + uint16_t addr = (uint16_t) btable_get_addr(EPindex, buf_id); TU_ASSERT(count <= xfer->max_packet_size, /**/); @@ -630,7 +621,6 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { uint8_t const dir = tu_edpt_dir(ep_addr); const uint16_t packet_size = tu_edpt_packet_size(desc_ep); const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size); - uint16_t pma_addr; uint32_t wType; TU_ASSERT(ep_idx < FSDEV_EP_COUNT); @@ -658,7 +648,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { pcd_set_ep_address(USB, ep_idx, tu_edpt_number(ep_addr)); /* Create a packet memory buffer area. */ - pma_addr = dcd_pma_alloc(buffer_size, false); + uint16_t pma_addr = dcd_pma_alloc(buffer_size, false); if (dir == TUSB_DIR_IN) { pcd_set_ep_tx_address(USB, ep_idx, pma_addr); @@ -732,11 +722,9 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet uint32_t pma_addr = dcd_pma_alloc(buffer_size, true); uint16_t pma_addr2 = pma_addr; #endif - pcd_set_ep_tx_address(USB, ep_idx, pma_addr); - pcd_set_ep_rx_address(USB, ep_idx, pma_addr2); - + btable_set_addr(ep_idx, 0, pma_addr); + btable_set_addr(ep_idx, 1, pma_addr2); pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS); - xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; return true; @@ -770,8 +758,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoin } // Currently, single-buffered, and only 64 bytes at a time (max) -static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) -{ +static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = (uint16_t)(xfer->total_len - xfer->queued_len); if (len > xfer->max_packet_size) { len = xfer->max_packet_size; @@ -779,20 +766,15 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) uint16_t ep_reg = pcd_get_endpoint(USB, ep_ix); bool const is_iso = (ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; - uint16_t addr_ptr; + uint8_t buf_id; if (is_iso) { - if (ep_reg & USB_EP_DTOG_TX) { - addr_ptr = pcd_get_ep_dbuf1_address(USB, ep_ix); - pcd_set_ep_tx_dbuf1_cnt(USB, ep_ix, len); - } else { - addr_ptr = pcd_get_ep_dbuf0_address(USB, ep_ix); - pcd_set_ep_tx_dbuf0_cnt(USB, ep_ix, len); - } + buf_id = (ep_reg & USB_EP_DTOG_TX) ? 1 : 0; } else { - addr_ptr = pcd_get_ep_tx_address(USB, ep_ix); - pcd_set_ep_tx_cnt(USB, ep_ix, len); + buf_id = 0; } + uint16_t addr_ptr = (uint16_t) btable_get_addr(ep_ix, buf_id); + btable_set_count(ep_ix, buf_id, len); if (xfer->ff) { dcd_write_packet_memory_ff(xfer->ff, addr_ptr, len); diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 58a9ed96d..72db609cb 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -69,7 +69,7 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b // 16-bit or 32-bit depending on FSDEV_BUS_32BIT. typedef struct { union { - // 0: tx, 1: rx + // 0: TX (IN), 1: RX (OUT) // strictly 16-bit access (could be 32-bit aligned) struct { @@ -239,9 +239,6 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USB return btable_get_count(bEpIdx, 1); } -#define pcd_get_ep_dbuf0_cnt pcd_get_ep_tx_cnt -#define pcd_get_ep_dbuf1_cnt pcd_get_ep_rx_cnt - TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { (void) USBx; return btable_get_addr(bEpIdx, 0); @@ -252,10 +249,6 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * return btable_get_addr(bEpIdx, 1); } -#define pcd_get_ep_dbuf0_address pcd_get_ep_tx_address -#define pcd_get_ep_dbuf1_address pcd_get_ep_rx_address - - TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t is_rx, uint16_t addr) { #ifdef FSDEV_BUS_32BIT uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr; @@ -288,26 +281,11 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USB btable_set_addr(bEpIdx, 1, addr); } -#define pcd_set_ep_dbuf0_address pcd_set_ep_tx_address -#define pcd_set_ep_dbuf1_address pcd_set_ep_rx_address - TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { (void) USBx; btable_set_count(bEpIdx, 0, wCount); } -#define pcd_set_ep_tx_dbuf0_cnt pcd_set_ep_tx_cnt - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_dbuf1_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); -#else - volatile uint16_t * reg = pcd_ep_rx_cnt_ptr(USBx, bEpIdx); - *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); -#endif -} - TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDef * USBx, uint32_t rxtx_idx, uint32_t blocksize, uint32_t numblocks) { /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ -- cgit v1.3.1 From 749f0921745ffe3647e6955b41b15e9643f3f3c4 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Jul 2024 12:46:09 +0700 Subject: refactor btable_set_rx_bufsize() --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 23 ++--- src/portable/st/stm32_fsdev/fsdev_common.h | 122 ++++++-------------------- 2 files changed, 41 insertions(+), 104 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index fc1627a1c..cd00e6395 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -370,7 +370,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) if (wEPRegVal & USB_EP_SETUP) { /* Setup packet */ - uint32_t count = pcd_get_ep_rx_cnt(USB, EPindex); + uint32_t count = btable_get_count(EPindex, BTABLE_BUF_RX); // Setup packet should always be 8 bytes. If not, ignore it, and try again. if (count == 8) { // Must reset EP to NAK (in case it had been stalling) @@ -387,13 +387,14 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) pcd_rx_dtog(USB, 0); } + uint16_t rx_addr = btable_get_addr(EPindex, BTABLE_BUF_RX); #ifdef FSDEV_BUS_32BIT - dcd_event_setup_received(0, (uint8_t *)(USB_PMAADDR + pcd_get_ep_rx_address(USB, EPindex)), true); + dcd_event_setup_received(0, (uint8_t *)(USB_PMAADDR + rx_addr), true); #else // The setup_received function uses memcpy, so this must first copy the setup data into // user memory, to allow for the 32-bit access that memcpy performs. uint8_t userMemBuf[8]; - dcd_read_packet_memory(userMemBuf, pcd_get_ep_rx_address(USB, EPindex), 8); + dcd_read_packet_memory(userMemBuf, rx_addr, 8); dcd_event_setup_received(0, (uint8_t*) userMemBuf, true); #endif } @@ -434,7 +435,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) if ((wEPRegVal & USB_EP_TYPE_MASK) != USB_EP_ISOCHRONOUS) { uint16_t remaining = xfer->total_len - xfer->queued_len; uint16_t cnt = tu_min16(remaining, xfer->max_packet_size); - pcd_set_ep_rx_cnt(USB, EPindex, cnt); + btable_set_rx_bufsize(EPindex, BTABLE_BUF_RX, cnt); } pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); } @@ -445,7 +446,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) // (Based on the docs, it seems SETUP will always be accepted after CTR is cleared) if (ep_addr == 0u) { // Always be prepared for a status packet... - pcd_set_ep_rx_cnt(USB, EPindex, CFG_TUD_ENDPOINT0_SIZE); + btable_set_rx_bufsize(EPindex, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); pcd_clear_rx_ep_ctr(USB, EPindex); } } @@ -651,11 +652,11 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { uint16_t pma_addr = dcd_pma_alloc(buffer_size, false); if (dir == TUSB_DIR_IN) { - pcd_set_ep_tx_address(USB, ep_idx, pma_addr); + btable_set_addr(ep_idx, BTABLE_BUF_TX, pma_addr); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); pcd_clear_tx_dtog(USB, ep_idx); } else { - pcd_set_ep_rx_address(USB, ep_idx, pma_addr); + btable_set_addr(ep_idx, BTABLE_BUF_RX, pma_addr); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK); pcd_clear_rx_dtog(USB, ep_idx); } @@ -771,7 +772,7 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { if (is_iso) { buf_id = (ep_reg & USB_EP_DTOG_TX) ? 1 : 0; } else { - buf_id = 0; + buf_id = BTABLE_BUF_TX; } uint16_t addr_ptr = (uint16_t) btable_get_addr(ep_ix, buf_id); btable_set_count(ep_ix, buf_id, len); @@ -806,10 +807,10 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx); if ((ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { - pcd_set_ep_rx_dbuf0_cnt(USB, ep_idx, cnt); - pcd_set_ep_rx_dbuf1_cnt(USB, ep_idx, cnt); + btable_set_rx_bufsize(ep_idx, 0, cnt); + btable_set_rx_bufsize(ep_idx, 1, cnt); } else { - pcd_set_ep_rx_cnt(USB, ep_idx, cnt); + btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); } pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_VALID); diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 72db609cb..05354d705 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -62,6 +62,11 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b #define pma_aligned #endif +enum { + BTABLE_BUF_TX = 0, + BTABLE_BUF_RX = 1 +}; + // hardware limit endpoint #define FSDEV_EP_COUNT 8 @@ -105,20 +110,6 @@ static volatile uint32_t * const pma32 = (volatile uint32_t*)USB_PMAADDR; typedef uint16_t fsdev_bus_t; // Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; - -TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) { - size_t total_word_offset = (((USBx)->BTABLE)>>1) + x; - total_word_offset *= FSDEV_PMA_STRIDE; - return &(pma[total_word_offset]); -} - -TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) { - return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 1u); -} - -TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) { - return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 3u); -} #endif /* Aligned buffer size according to hardware */ @@ -205,100 +196,47 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, pcd_set_endpoint(USBx, bEpIdx,regVal); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t is_rx) { +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { uint16_t count; #ifdef FSDEV_BUS_32BIT - count = (FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr >> 16); + count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16); #else - count = FSDEV_BTABLE->ep16[ep_id][is_rx].count; + count = FSDEV_BTABLE->ep16[ep_id][buf_id].count; #endif return count & 0x3FFU; } -TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t is_rx) { +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) { #ifdef FSDEV_BUS_32BIT - return FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr & 0x0000FFFFu; + return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu; #else - return FSDEV_BTABLE->ep16[ep_id][is_rx].addr; + return FSDEV_BTABLE->ep16[ep_id][buf_id].addr; #endif } -/** - * @brief gets counter of the tx buffer. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @retval Counter value - */ -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { - (void) USBx; - return btable_get_count(bEpIdx, 0); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { - (void) USBx; - return btable_get_count(bEpIdx, 1); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { - (void) USBx; - return btable_get_addr(bEpIdx, 0); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { - (void) USBx; - return btable_get_addr(bEpIdx, 1); -} - -TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t is_rx, uint16_t addr) { +TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) { #ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr; + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); - FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr = count_addr; + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; #else - FSDEV_BTABLE->ep16[ep_id][is_rx].addr = addr; + FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr; #endif } -TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t is_rx, uint16_t byte_count) { +TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) { #ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr; + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16); - FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr = count_addr; + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; #else - uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][is_rx].count; + uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count; cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU); - FSDEV_BTABLE->ep16[ep_id][is_rx].count = cnt; + FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt; #endif } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { - (void) USBx; - btable_set_addr(bEpIdx, 0, addr); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { - (void) USBx; - btable_set_addr(bEpIdx, 1, addr); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { - (void) USBx; - btable_set_count(bEpIdx, 0, wCount); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDef * USBx, uint32_t rxtx_idx, - uint32_t blocksize, uint32_t numblocks) { - /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ -#ifdef FSDEV_BUS_32BIT - (void) USBx; - pma32[rxtx_idx] = (pma32[rxtx_idx] & 0x0000FFFFu) | (blocksize << 31) | ((numblocks - blocksize) << 26); -#else - volatile uint16_t *pdwReg = pcd_btable_word_ptr(USBx, rxtx_idx*2u + 1u); - *pdwReg = (blocksize << 15) | ((numblocks - blocksize) << 10); -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx, uint32_t rxtx_idx, uint32_t wCount) { +TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint32_t wCount) { wCount = pcd_aligned_buffer_size(wCount); /* We assume that the buffer size is already aligned to hardware requirements. */ @@ -309,19 +247,17 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx, TU_ASSERT((wCount - (numblocks * (blocksize ? 32 : 2))) == 0, /**/); /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ - pcd_set_ep_blsize_num_blocks(USBx, rxtx_idx, blocksize, numblocks); -} + uint16_t bl_nb = (blocksize << 15) | ((numblocks - blocksize) << 10); -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_dbuf0_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { - pcd_set_ep_bufsize(USBx, 2*bEpIdx, wCount); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { - pcd_set_ep_bufsize(USBx, 2*bEpIdx + 1, wCount); +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; +#else + FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb; +#endif } -#define pcd_set_ep_rx_dbuf1_cnt pcd_set_ep_rx_cnt - /** * @brief sets the status for tx transfer (bits STAT_TX[1:0]). * @param USBx USB peripheral instance register address. -- cgit v1.3.1 From b15814b2f9579ef126b2ad30b6fff0e338ead3ef Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Jul 2024 16:29:54 +0700 Subject: move align buffer to pma_alloc() --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 32 +++--- src/portable/st/stm32_fsdev/fsdev_common.h | 140 +++++++++++++------------- 2 files changed, 85 insertions(+), 87 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index cd00e6395..2be6ef031 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -170,7 +170,7 @@ static void dcd_ep_ctr_handler(void); // PMA allocation/access static uint16_t ep_buf_ptr; ///< Points to first free memory location -static uint32_t dcd_pma_alloc(uint16_t length, bool dbuf); +static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf); static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type); static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes); static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes); @@ -551,21 +551,19 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *req * In case of double buffering, high 16bit is the address of 2nd buffer * During failure, TU_ASSERT is used. If this happens, rework/reallocate memory manually. */ -static uint32_t dcd_pma_alloc(uint16_t length, bool dbuf) +static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf) { - // Ensure allocated buffer is aligned -#ifdef FSDEV_BUS_32BIT - length = (length + 3) & ~0x03; -#else - length = (length + 1) & ~0x01; -#endif + uint8_t blsize, num_block; + uint16_t aligned_len = pma_align_buffer_size(len, &blsize, &num_block); + (void) blsize; + (void) num_block; uint32_t addr = ep_buf_ptr; - ep_buf_ptr = (uint16_t)(ep_buf_ptr + length); // increment buffer pointer + ep_buf_ptr = (uint16_t)(ep_buf_ptr + aligned_len); // increment buffer pointer if (dbuf) { addr |= ((uint32_t)ep_buf_ptr) << 16; - ep_buf_ptr = (uint16_t)(ep_buf_ptr + length); // increment buffer pointer + ep_buf_ptr = (uint16_t)(ep_buf_ptr + aligned_len); // increment buffer pointer } // Verify packet buffer is not overflowed @@ -621,11 +619,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); uint8_t const dir = tu_edpt_dir(ep_addr); const uint16_t packet_size = tu_edpt_packet_size(desc_ep); - const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size); uint32_t wType; TU_ASSERT(ep_idx < FSDEV_EP_COUNT); - TU_ASSERT(buffer_size <= 64); // Set type switch (desc_ep->bmAttributes.xfer) { @@ -649,7 +645,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { pcd_set_ep_address(USB, ep_idx, tu_edpt_number(ep_addr)); /* Create a packet memory buffer area. */ - uint16_t pma_addr = dcd_pma_alloc(buffer_size, false); + uint16_t pma_addr = dcd_pma_alloc(packet_size, false); if (dir == TUSB_DIR_IN) { btable_set_addr(ep_idx, BTABLE_BUF_TX, pma_addr); @@ -707,22 +703,20 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) } } -bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) -{ +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; uint8_t const ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS); - const uint16_t buffer_size = pcd_aligned_buffer_size(largest_packet_size); /* Create a packet memory buffer area. Enable double buffering for devices with 2048 bytes PMA, for smaller devices double buffering occupy too much space. */ + uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, true); #if FSDEV_PMA_SIZE > 1024u - uint32_t pma_addr = dcd_pma_alloc(buffer_size, true); uint16_t pma_addr2 = pma_addr >> 16; #else - uint32_t pma_addr = dcd_pma_alloc(buffer_size, true); uint16_t pma_addr2 = pma_addr; #endif + btable_set_addr(ep_idx, 0, pma_addr); btable_set_addr(ep_idx, 1, pma_addr2); pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS); @@ -803,7 +797,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) if (dir == TUSB_DIR_IN) { dcd_transmit_packet(xfer, ep_idx); } else { - uint32_t cnt = (uint32_t ) tu_min16(xfer->total_len, xfer->max_packet_size); + uint32_t cnt = (uint32_t) tu_min16(xfer->total_len, xfer->max_packet_size); uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx); if ((ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 05354d705..c8d259cfa 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -96,7 +96,7 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE #define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) //--------------------------------------------------------------------+ -// Helper +// BTable //--------------------------------------------------------------------+ // The fsdev_bus_t type can be used for both register and PMA access necessities @@ -112,18 +112,84 @@ typedef uint16_t fsdev_bus_t; static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; #endif +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) { +#ifdef FSDEV_BUS_32BIT + return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu; +#else + return FSDEV_BTABLE->ep16[ep_id][buf_id].addr; +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) { +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; +#else + FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr; +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { + uint16_t count; +#ifdef FSDEV_BUS_32BIT + count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16); +#else + count = FSDEV_BTABLE->ep16[ep_id][buf_id].count; +#endif + return count & 0x3FFU; +} + +TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) { +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; +#else + uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count; + cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU); + FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt; +#endif +} + /* Aligned buffer size according to hardware */ -TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t size) { +TU_ATTR_ALWAYS_INLINE static inline uint16_t pma_align_buffer_size(uint16_t size, uint8_t* blsize, uint8_t* num_block) { /* The STM32 full speed USB peripheral supports only a limited set of * buffer sizes given by the RX buffer entry format in the USB_BTABLE. */ - uint16_t blocksize = (size > 62) ? 32 : 2; + uint16_t block_in_bytes; + if (size > 62) { + block_in_bytes = 32; + *blsize = 1; + } else { + block_in_bytes = 2; + *blsize = 0; + } + + *num_block = tu_div_ceil(size, block_in_bytes); - // Round up while dividing requested size by blocksize - uint16_t numblocks = (size + blocksize - 1) / blocksize ; + return (*num_block) * block_in_bytes; +} + +TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint32_t wCount) { + uint8_t blsize, num_block; + (void) pma_align_buffer_size(wCount, &blsize, &num_block); - return numblocks * blocksize; + /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ + uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10); + +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; +#else + FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb; +#endif } +//--------------------------------------------------------------------+ +// Endpoint +//--------------------------------------------------------------------+ + TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) { #ifdef FSDEV_BUS_32BIT (void) USBx; @@ -196,68 +262,6 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, pcd_set_endpoint(USBx, bEpIdx,regVal); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { - uint16_t count; -#ifdef FSDEV_BUS_32BIT - count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16); -#else - count = FSDEV_BTABLE->ep16[ep_id][buf_id].count; -#endif - return count & 0x3FFU; -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) { -#ifdef FSDEV_BUS_32BIT - return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu; -#else - return FSDEV_BTABLE->ep16[ep_id][buf_id].addr; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) { -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; - count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); - FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; -#else - FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) { -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; - count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16); - FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; -#else - uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count; - cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU); - FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint32_t wCount) { - wCount = pcd_aligned_buffer_size(wCount); - - /* We assume that the buffer size is already aligned to hardware requirements. */ - uint16_t blocksize = (wCount > 62) ? 1 : 0; - uint16_t numblocks = wCount / (blocksize ? 32 : 2); - - /* There should be no remainder in the above calculation */ - TU_ASSERT((wCount - (numblocks * (blocksize ? 32 : 2))) == 0, /**/); - - /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ - uint16_t bl_nb = (blocksize << 15) | ((numblocks - blocksize) << 10); - -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; - count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu); - FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; -#else - FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb; -#endif -} - /** * @brief sets the status for tx transfer (bits STAT_TX[1:0]). * @param USBx USB peripheral instance register address. -- cgit v1.3.1 From 1cf8e34ae5fc6466d07ac438691391c7a5a809ff Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Jul 2024 20:32:26 +0700 Subject: improve set endpoint --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 41 +++++----- src/portable/st/stm32_fsdev/fsdev_ch32.h | 35 ++++----- src/portable/st/stm32_fsdev/fsdev_common.h | 104 +++++++++++++++++--------- src/portable/st/stm32_fsdev/fsdev_stm32.h | 17 +++++ 4 files changed, 125 insertions(+), 72 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 2be6ef031..6007b4a02 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -616,24 +616,24 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void)rhport; uint8_t const ep_addr = desc_ep->bEndpointAddress; - uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); uint8_t const dir = tu_edpt_dir(ep_addr); const uint16_t packet_size = tu_edpt_packet_size(desc_ep); - uint32_t wType; - + uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); TU_ASSERT(ep_idx < FSDEV_EP_COUNT); + uint32_t ep_reg = FSDEV_REG->ep[ep_idx].reg & ~USB_EPREG_MASK; + ep_reg |= tu_edpt_number(ep_addr) | USB_EP_CTR_RX | USB_EP_CTR_TX; + // Set type switch (desc_ep->bmAttributes.xfer) { case TUSB_XFER_CONTROL: - wType = USB_EP_CONTROL; + ep_reg |= USB_EP_CONTROL; break; case TUSB_XFER_BULK: - wType = USB_EP_CONTROL; + ep_reg |= USB_EP_CONTROL; // FIXME should it be bulk? break; - case TUSB_XFER_INTERRUPT: - wType = USB_EP_INTERRUPT; + ep_reg |= USB_EP_INTERRUPT; break; default: @@ -641,24 +641,23 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { TU_ASSERT(false); } - pcd_set_eptype(USB, ep_idx, wType); - pcd_set_ep_address(USB, ep_idx, tu_edpt_number(ep_addr)); - /* Create a packet memory buffer area. */ uint16_t pma_addr = dcd_pma_alloc(packet_size, false); + btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr); + + xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size; + xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; if (dir == TUSB_DIR_IN) { - btable_set_addr(ep_idx, BTABLE_BUF_TX, pma_addr); - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); - pcd_clear_tx_dtog(USB, ep_idx); + ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK); + ep_reg = ep_add_tx_dtog(ep_reg, 0); + ep_reg &= ~(USB_EPRX_STAT | USB_EP_DTOG_RX); } else { - btable_set_addr(ep_idx, BTABLE_BUF_RX, pma_addr); - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK); - pcd_clear_rx_dtog(USB, ep_idx); + ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); + ep_reg = ep_add_rx_dtog(ep_reg, 0); + ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX); } - - xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size; - xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; + pcd_set_endpoint(USB, ep_idx, ep_reg); return true; } @@ -731,7 +730,8 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoin uint8_t const ep_addr = p_endpoint_desc->bEndpointAddress; uint8_t const ep_idx = xfer_ctl_ptr(ep_addr)->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); - const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc); + + xfer_ctl_ptr(ep_addr)->max_packet_size = tu_edpt_packet_size(p_endpoint_desc); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); @@ -747,7 +747,6 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoin pcd_tx_dtog(USB, ep_idx); } - xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size; return true; } diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h index f63a80d56..81ef08b8a 100644 --- a/src/portable/st/stm32_fsdev/fsdev_ch32.h +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -55,28 +55,29 @@ #define FSDEV_PMA_SIZE (512u) +#if 1 // volatile 32-bit aligned -#define _va32 volatile TU_ATTR_ALIGNED(4) +#define _vaa32 volatile TU_ATTR_ALIGNED(4) typedef struct { - _va32 uint16_t EP0R; // 00: USB Endpoint 0 register - _va32 uint16_t EP1R; // 04: USB Endpoint 1 register - _va32 uint16_t EP2R; // 08: USB Endpoint 2 register - _va32 uint16_t EP3R; // 0C: USB Endpoint 3 register - _va32 uint16_t EP4R; // 10: USB Endpoint 4 register - _va32 uint16_t EP5R; // 14: USB Endpoint 5 register - _va32 uint16_t EP6R; // 18: USB Endpoint 6 register - _va32 uint16_t EP7R; // 1C: USB Endpoint 7 register - _va32 uint16_t RESERVED7[16]; // Reserved - _va32 uint16_t CNTR; // 40: Control register - _va32 uint16_t ISTR; // 44: Interrupt status register - _va32 uint16_t FNR; // 48: Frame number register - _va32 uint16_t DADDR; // 4C: Device address register - _va32 uint16_t BTABLE; // 50: Buffer Table address register + _vaa32 uint16_t EP0R; // 00: USB Endpoint 0 register + _vaa32 uint16_t EP1R; // 04: USB Endpoint 1 register + _vaa32 uint16_t EP2R; // 08: USB Endpoint 2 register + _vaa32 uint16_t EP3R; // 0C: USB Endpoint 3 register + _vaa32 uint16_t EP4R; // 10: USB Endpoint 4 register + _vaa32 uint16_t EP5R; // 14: USB Endpoint 5 register + _vaa32 uint16_t EP6R; // 18: USB Endpoint 6 register + _vaa32 uint16_t EP7R; // 1C: USB Endpoint 7 register + _vaa32 uint16_t RESERVED7[16]; // Reserved + _vaa32 uint16_t CNTR; // 40: Control register + _vaa32 uint16_t ISTR; // 44: Interrupt status register + _vaa32 uint16_t FNR; // 48: Frame number register + _vaa32 uint16_t DADDR; // 4C: Device address register + _vaa32 uint16_t BTABLE; // 50: Buffer Table address register } USB_TypeDef; +#endif -TU_VERIFY_STATIC(sizeof(USB_TypeDef) == 0x54, "Size is not correct"); -TU_VERIFY_STATIC(offsetof(USB_TypeDef, CNTR) == 0x40, "Wrong offset"); +#define FSDEV_REG_BASE 0x40005C00UL #define USB_BASE (APB1PERIPH_BASE + 0x00005C00UL) /*!< USB_IP Peripheral Registers base address */ #define USB_PMAADDR (APB1PERIPH_BASE + 0x00006000UL) /*!< USB_IP Packet Memory Area base address */ diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index c8d259cfa..3d1e1fe4a 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -95,9 +95,8 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE #define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) -//--------------------------------------------------------------------+ -// BTable -//--------------------------------------------------------------------+ +// volatile 32-bit aligned +#define _va32 volatile TU_ATTR_ALIGNED(4) // The fsdev_bus_t type can be used for both register and PMA access necessities // For type-safety create a new macro for the volatile address of PMAADDR @@ -112,6 +111,39 @@ typedef uint16_t fsdev_bus_t; static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; #endif +typedef struct { +// _va32 fsdev_bus_t EP0R; // 00: USB Endpoint 0 register +// _va32 fsdev_bus_t EP1R; // 04: USB Endpoint 1 register +// _va32 fsdev_bus_t EP2R; // 08: USB Endpoint 2 register +// _va32 fsdev_bus_t EP3R; // 0C: USB Endpoint 3 register +// _va32 fsdev_bus_t EP4R; // 10: USB Endpoint 4 register +// _va32 fsdev_bus_t EP5R; // 14: USB Endpoint 5 register +// _va32 fsdev_bus_t EP6R; // 18: USB Endpoint 6 register +// _va32 fsdev_bus_t EP7R; // 1C: USB Endpoint 7 register + struct { + _va32 fsdev_bus_t reg; + }ep[FSDEV_EP_COUNT]; + + _va32 uint32_t RESERVED7[8]; // Reserved + _va32 fsdev_bus_t CNTR; // 40: Control register + _va32 fsdev_bus_t ISTR; // 44: Interrupt status register + _va32 fsdev_bus_t FNR; // 48: Frame number register + _va32 fsdev_bus_t DADDR; // 4C: Device address register + _va32 fsdev_bus_t BTABLE; // 50: Buffer Table address register (16-bit only) + _va32 fsdev_bus_t LPMCSR; // 54: LPM Control and Status Register (32-bit only) + _va32 fsdev_bus_t BCDR; // 58: Battery Charging Detector Register (32-bit only) +} fsdev_regs_t; + +TU_VERIFY_STATIC(offsetof(fsdev_regs_t, CNTR) == 0x40, "Wrong offset"); +TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); + +#define FSDEV_REG ((fsdev_regs_t*) FSDEV_REG_BASE) + + +//--------------------------------------------------------------------+ +// BTable +//--------------------------------------------------------------------+ + TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) { #ifdef FSDEV_BUS_32BIT return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu; @@ -191,24 +223,13 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - volatile uint32_t *reg = (volatile uint32_t *)(USB_DRD_BASE + bEpIdx*4); - *reg = wRegValue; -#else - volatile uint16_t *reg = (volatile uint16_t *)((&USBx->EP0R) + bEpIdx*2u); - *reg = (uint16_t)wRegValue; -#endif + FSDEV_REG->ep[bEpIdx].reg = (fsdev_bus_t) wRegValue; } TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - volatile const uint32_t *reg = (volatile const uint32_t *)(USB_DRD_BASE + bEpIdx*4); -#else - volatile const uint16_t *reg = (volatile const uint16_t *)((&USBx->EP0R) + bEpIdx*2u); -#endif - return *reg; + return FSDEV_REG->ep[bEpIdx].reg; } /** @@ -262,6 +283,21 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, pcd_set_endpoint(USBx, bEpIdx,regVal); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_status(uint32_t reg, uint32_t state) { + return reg | ((reg ^ state) & USB_EPTX_STAT); +} +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_status(uint32_t reg, uint32_t state) { + return reg | ((reg ^ state) & USB_EPRX_STAT); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_dtog(uint32_t reg, uint32_t state) { + return reg | ((reg ^ state) & USB_EP_DTOG_TX); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_dtog(uint32_t reg, uint32_t state) { + return reg | ((reg ^ state) & USB_EP_DTOG_RX); +} + /** * @brief sets the status for tx transfer (bits STAT_TX[1:0]). * @param USBx USB peripheral instance register address. @@ -293,10 +329,10 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx pcd_set_endpoint(USBx, bEpIdx, regVal); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - return (regVal & USB_EPRX_STAT) >> (12u); -} +//TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) { +// uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); +// return (regVal & USB_EPRX_STAT) >> (12u); +//} TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); @@ -326,20 +362,20 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, } } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal |= USB_EP_KIND; - regVal &= USB_EPREG_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPKIND_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} +//TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { +// uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); +// regVal |= USB_EP_KIND; +// regVal &= USB_EPREG_MASK; +// regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; +// pcd_set_endpoint(USBx, bEpIdx, regVal); +//} +// +//TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { +// uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); +// regVal &= USB_EPKIND_MASK; +// regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; +// pcd_set_endpoint(USBx, bEpIdx, regVal); +//} #ifdef __cplusplus } diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index a8f61a35f..f89882e0d 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -35,6 +35,7 @@ #if CFG_TUSB_MCU == OPT_MCU_STM32F0 #include "stm32f0xx.h" #define FSDEV_PMA_SIZE (1024u) + #define FSDEV_REG_BASE USB_BASE // F0x2 models are crystal-less // All have internal D+ pull-up // 070RB: 2 x 16 bits/word memory LPM Support, BCD Support @@ -193,6 +194,22 @@ // This includes U0 #endif +#if defined(USB_BASE) + #define FSDEV_REG_BASE USB_BASE +#elif defined(USB_DRD_BASE) + #define FSDEV_REG_BASE USB_DRD_BASE +#else + #error "FSDEV_REG_BASE not defined" +#endif + +#ifndef USB_EPTX_STAT +#define USB_EPTX_STAT 0x0030U +#endif + +#ifndef USB_EPRX_STAT +#define USB_EPRX_STAT 0x3000U +#endif + // This checks if the device has "LPM" #if defined(USB_ISTR_L1REQ) #define USB_ISTR_L1REQ_FORCED (USB_ISTR_L1REQ) -- cgit v1.3.1 From f4aaad6869db74a4fba6eeb716d20be85978a311 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Jul 2024 21:35:24 +0700 Subject: add edpt0_open(), slightly update dtog --- src/device/dcd.h | 2 +- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 74 +++++++++++++++------------ src/portable/st/stm32_fsdev/fsdev_common.h | 30 +++++++---- src/portable/st/stm32_fsdev/fsdev_stm32.h | 8 --- 4 files changed, 62 insertions(+), 52 deletions(-) diff --git a/src/device/dcd.h b/src/device/dcd.h index b25b47025..41e0fbee3 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -180,7 +180,7 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); TU_ATTR_WEAK bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size); // Configure and enable an ISO endpoint according to descriptor -TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc); +TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); //--------------------------------------------------------------------+ // Event API (implemented by stack) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 6007b4a02..834de6998 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -178,6 +178,8 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes); static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes); +TU_ATTR_UNUSED static void edpt0_open(uint8_t rhport); + //--------------------------------------------------------------------+ // Inline helper //--------------------------------------------------------------------+ @@ -277,19 +279,7 @@ static void handle_bus_reset(uint8_t rhport) { // Reset PMA allocation ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT; - tusb_desc_endpoint_t ep0_desc = { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = 0x00, - .bmAttributes = {.xfer = TUSB_XFER_CONTROL}, - .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, - .bInterval = 0 - }; - - dcd_edpt_open(rhport, &ep0_desc); - - ep0_desc.bEndpointAddress = 0x80; - dcd_edpt_open(rhport, &ep0_desc); + edpt0_open(rhport); // open control endpoint (both IN & OUT) USB->DADDR = USB_DADDR_EF; // Enable USB Function } @@ -610,8 +600,32 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) TU_ASSERT(0); } -// The STM32F0 doesn't seem to like |= or &= to manipulate the EP#R registers, -// so I'm using the #define from HAL here, instead. +void edpt0_open(uint8_t rhport) { + (void) rhport; + + dcd_ep_alloc(0x0, TUSB_XFER_CONTROL); + dcd_ep_alloc(0x80, TUSB_XFER_CONTROL); + + xfer_status[0][0].max_packet_size = CFG_TUD_ENDPOINT0_SIZE; + xfer_status[0][0].ep_idx = 0; + + xfer_status[0][1].max_packet_size = CFG_TUD_ENDPOINT0_SIZE; + xfer_status[0][1].ep_idx = 0; + + uint16_t pma_addr0 = dcd_pma_alloc(CFG_TUD_ENDPOINT0_SIZE, false); + uint16_t pma_addr1 = dcd_pma_alloc(CFG_TUD_ENDPOINT0_SIZE, false); + + btable_set_addr(0, BTABLE_BUF_RX, pma_addr0); + btable_set_addr(0, BTABLE_BUF_TX, pma_addr1); + + uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; + ep_reg |= USB_EP_CONTROL | USB_EP_CTR_RX | USB_EP_CTR_TX; + ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK); + ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); + // no need to explicitly set DTOG bits since we aren't masked DTOG bit + + pcd_set_endpoint(USB, 0, ep_reg); +} bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void)rhport; @@ -626,9 +640,6 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { // Set type switch (desc_ep->bmAttributes.xfer) { - case TUSB_XFER_CONTROL: - ep_reg |= USB_EP_CONTROL; - break; case TUSB_XFER_BULK: ep_reg |= USB_EP_CONTROL; // FIXME should it be bulk? break; @@ -718,35 +729,34 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet btable_set_addr(ep_idx, 0, pma_addr); btable_set_addr(ep_idx, 1, pma_addr2); - pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS); xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; + pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS); + return true; } -bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) -{ +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void)rhport; - uint8_t const ep_addr = p_endpoint_desc->bEndpointAddress; + uint8_t const ep_addr = desc_ep->bEndpointAddress; uint8_t const ep_idx = xfer_ctl_ptr(ep_addr)->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); - xfer_ctl_ptr(ep_addr)->max_packet_size = tu_edpt_packet_size(p_endpoint_desc); - - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); + xfer_ctl_ptr(ep_addr)->max_packet_size = tu_edpt_packet_size(desc_ep); - pcd_set_ep_address(USB, ep_idx, tu_edpt_number(ep_addr)); - - pcd_clear_tx_dtog(USB, ep_idx); - pcd_clear_rx_dtog(USB, ep_idx); + uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; + ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX; + ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_DIS); + ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_DIS); + // no need to explicitly set DTOG bits since we aren't masked DTOG bit if (dir == TUSB_DIR_IN) { - pcd_rx_dtog(USB, ep_idx); + ep_reg = ep_add_rx_dtog(ep_reg, 1); } else { - pcd_tx_dtog(USB, ep_idx); + ep_reg = ep_add_tx_dtog(ep_reg, 1); } + pcd_set_endpoint(USB, ep_idx, ep_reg); return true; } diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 3d1e1fe4a..53b2af0a2 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -112,14 +112,6 @@ static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; #endif typedef struct { -// _va32 fsdev_bus_t EP0R; // 00: USB Endpoint 0 register -// _va32 fsdev_bus_t EP1R; // 04: USB Endpoint 1 register -// _va32 fsdev_bus_t EP2R; // 08: USB Endpoint 2 register -// _va32 fsdev_bus_t EP3R; // 0C: USB Endpoint 3 register -// _va32 fsdev_bus_t EP4R; // 10: USB Endpoint 4 register -// _va32 fsdev_bus_t EP5R; // 14: USB Endpoint 5 register -// _va32 fsdev_bus_t EP6R; // 18: USB Endpoint 6 register -// _va32 fsdev_bus_t EP7R; // 1C: USB Endpoint 7 register struct { _va32 fsdev_bus_t reg; }ep[FSDEV_EP_COUNT]; @@ -140,6 +132,22 @@ TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); #define FSDEV_REG ((fsdev_regs_t*) FSDEV_REG_BASE) +#ifndef USB_EPTX_STAT +#define USB_EPTX_STAT 0x0030U +#endif + +#ifndef USB_EPRX_STAT +#define USB_EPRX_STAT 0x3000U +#endif + +#ifndef USB_EP_DTOG_TX_Pos +#define USB_EP_DTOG_TX_Pos (6U) +#endif + +#ifndef USB_EP_DTOG_RX_Pos +#define USB_EP_DTOG_RX_Pos (14U) +#endif + //--------------------------------------------------------------------+ // BTable //--------------------------------------------------------------------+ @@ -244,7 +252,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, regVal &= USB_EPREG_MASK; regVal |= bAddr; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx,regVal); + pcd_set_endpoint(USBx, bEpIdx, regVal); } TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) { @@ -291,11 +299,11 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_status(uint32_t reg, uint } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_dtog(uint32_t reg, uint32_t state) { - return reg | ((reg ^ state) & USB_EP_DTOG_TX); + return reg | ((reg ^ (state << USB_EP_DTOG_TX_Pos)) & USB_EP_DTOG_TX); } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_dtog(uint32_t reg, uint32_t state) { - return reg | ((reg ^ state) & USB_EP_DTOG_RX); + return reg | ((reg ^ (state << USB_EP_DTOG_RX_Pos)) & USB_EP_DTOG_RX); } /** diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index f89882e0d..f20505f28 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -202,14 +202,6 @@ #error "FSDEV_REG_BASE not defined" #endif -#ifndef USB_EPTX_STAT -#define USB_EPTX_STAT 0x0030U -#endif - -#ifndef USB_EPRX_STAT -#define USB_EPRX_STAT 0x3000U -#endif - // This checks if the device has "LPM" #if defined(USB_ISTR_L1REQ) #define USB_ISTR_L1REQ_FORCED (USB_ISTR_L1REQ) -- cgit v1.3.1 From 0c8d41e25ec3f691f3125f634659f52d084e8995 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 09:46:31 +0700 Subject: correct ep toggle bit --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 32 +++++++++------------------ src/portable/st/stm32_fsdev/fsdev_common.h | 8 +++---- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 834de6998..5cba9ca40 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -350,8 +350,6 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) uint32_t wEPRegVal = pcd_get_endpoint(USB, EPindex); uint8_t ep_addr = wEPRegVal & USB_EPADDR_FIELD; - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); - // Verify the CTR_RX bit is set. This was in the ST Micro code, // but I'm not sure it's actually necessary? if ((wEPRegVal & USB_EP_CTR_RX) == 0U) { @@ -359,34 +357,26 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) } if (wEPRegVal & USB_EP_SETUP) { - /* Setup packet */ uint32_t count = btable_get_count(EPindex, BTABLE_BUF_RX); // Setup packet should always be 8 bytes. If not, ignore it, and try again. if (count == 8) { - // Must reset EP to NAK (in case it had been stalling) - pcd_set_ep_rx_status(USB, 0u, USB_EP_RX_NAK); - pcd_set_ep_tx_status(USB, 0u, USB_EP_TX_NAK); - - // set both data toggle to 1 - uint32_t regVal = pcd_get_endpoint(USB, 0); - if ((regVal & USB_EP_DTOG_TX) == 0) { - pcd_tx_dtog(USB, 0); - } - - if ((regVal & USB_EP_DTOG_RX) == 0) { - pcd_rx_dtog(USB, 0); - } - uint16_t rx_addr = btable_get_addr(EPindex, BTABLE_BUF_RX); #ifdef FSDEV_BUS_32BIT dcd_event_setup_received(0, (uint8_t *)(USB_PMAADDR + rx_addr), true); #else // The setup_received function uses memcpy, so this must first copy the setup data into // user memory, to allow for the 32-bit access that memcpy performs. - uint8_t userMemBuf[8]; + uint32_t userMemBuf[2]; dcd_read_packet_memory(userMemBuf, rx_addr, 8); dcd_event_setup_received(0, (uint8_t*) userMemBuf, true); #endif + + // Reset EP to NAK (in case it had been stalling) + wEPRegVal = ep_add_tx_status(wEPRegVal, USB_EP_TX_NAK); + wEPRegVal = ep_add_rx_status(wEPRegVal, USB_EP_RX_NAK); + wEPRegVal = ep_add_tx_dtog(wEPRegVal, 1); + wEPRegVal = ep_add_rx_dtog(wEPRegVal, 1); + pcd_set_endpoint(USB, 0, wEPRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX); } } else { // Clear RX CTR interrupt flag @@ -394,6 +384,8 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) pcd_clear_rx_ep_ctr(USB, EPindex); } + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + uint8_t buf_id; if ((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { // ISO endpoints are double buffered @@ -404,13 +396,11 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) uint32_t count = btable_get_count(EPindex, buf_id); uint16_t addr = (uint16_t) btable_get_addr(EPindex, buf_id); - TU_ASSERT(count <= xfer->max_packet_size, /**/); - if (count != 0U) { if (xfer->ff) { dcd_read_packet_memory_ff(xfer->ff, addr, count); } else { - dcd_read_packet_memory(&(xfer->buffer[xfer->queued_len]), addr, count); + dcd_read_packet_memory(xfer->buffer + xfer->queued_len, addr, count); } xfer->queued_len = (uint16_t)(xfer->queued_len + count); diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 53b2af0a2..09bf4c2ca 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -292,18 +292,18 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_status(uint32_t reg, uint32_t state) { - return reg | ((reg ^ state) & USB_EPTX_STAT); + return reg ^ state; } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_status(uint32_t reg, uint32_t state) { - return reg | ((reg ^ state) & USB_EPRX_STAT); + return reg ^ state; } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_dtog(uint32_t reg, uint32_t state) { - return reg | ((reg ^ (state << USB_EP_DTOG_TX_Pos)) & USB_EP_DTOG_TX); + return reg ^ (state << USB_EP_DTOG_TX_Pos); } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_dtog(uint32_t reg, uint32_t state) { - return reg | ((reg ^ (state << USB_EP_DTOG_RX_Pos)) & USB_EP_DTOG_RX); + return reg ^ (state << USB_EP_DTOG_RX_Pos); } /** -- cgit v1.3.1 From 126778298e6ab23f2117b60d479d31e4de7d276f Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 11:35:09 +0700 Subject: enhance dcd_ep_ctr_rx_handler() --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 128 ++++++++++++-------------- 1 file changed, 58 insertions(+), 70 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 5cba9ca40..c7a25ba5e 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -178,7 +178,7 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes); static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes); -TU_ATTR_UNUSED static void edpt0_open(uint8_t rhport); +static void edpt0_open(uint8_t rhport); //--------------------------------------------------------------------+ // Inline helper @@ -285,10 +285,8 @@ static void handle_bus_reset(uint8_t rhport) { } // Handle CTR interrupt for the TX/IN direction -// Upon call, (wIstr & USB_ISTR_DIR) == 0U -static void dcd_ep_ctr_tx_handler(uint32_t wIstr) { - uint32_t EPindex = wIstr & USB_ISTR_EP_ID; - uint32_t wEPRegVal = pcd_get_endpoint(USB, EPindex); +static void dcd_ep_ctr_tx_handler(uint32_t ep_id) { + uint32_t wEPRegVal = pcd_get_endpoint(USB, ep_id); uint8_t ep_addr = (wEPRegVal & USB_EPADDR_FIELD) | TUSB_DIR_IN_MASK; // Verify the CTR_TX bit is set. This was in the ST Micro code, @@ -298,7 +296,7 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) { } /* clear int flag */ - pcd_clear_tx_ep_ctr(USB, EPindex); + pcd_clear_tx_ep_ctr(USB, ep_id); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); @@ -311,20 +309,18 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) { } xfer->iso_in_sending = false; uint8_t buf_id = (wEPRegVal & USB_EP_DTOG_TX) ? 0 : 1; - btable_set_count(EPindex, buf_id, 0); + btable_set_count(ep_id, buf_id, 0); } if ((xfer->total_len != xfer->queued_len)) { - dcd_transmit_packet(xfer, EPindex); + dcd_transmit_packet(xfer, ep_id); } else { dcd_event_xfer_complete(0, ep_addr, xfer->total_len, XFER_RESULT_SUCCESS, true); } } // Handle CTR interrupt for the RX/OUT direction -// Upon call, (wIstr & USB_ISTR_DIR) == 0U -static void dcd_ep_ctr_rx_handler(uint32_t wIstr) -{ +static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { #ifdef FSDEV_BUS_32BIT /* https://www.st.com/resource/en/errata_sheet/es0561-stm32h503cbebkbrb-device-errata-stmicroelectronics.pdf * From STM32H503 errata 2.15.1: Buffer description table update completes after CTR interrupt triggers @@ -346,103 +342,92 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) } #endif - uint32_t EPindex = wIstr & USB_ISTR_EP_ID; - uint32_t wEPRegVal = pcd_get_endpoint(USB, EPindex); - uint8_t ep_addr = wEPRegVal & USB_EPADDR_FIELD; + uint32_t ep_reg = pcd_get_endpoint(USB, ep_id); + uint8_t ep_addr = ep_reg & USB_EPADDR_FIELD; // Verify the CTR_RX bit is set. This was in the ST Micro code, // but I'm not sure it's actually necessary? - if ((wEPRegVal & USB_EP_CTR_RX) == 0U) { + if ((ep_reg & USB_EP_CTR_RX) == 0U) { return; } - if (wEPRegVal & USB_EP_SETUP) { - uint32_t count = btable_get_count(EPindex, BTABLE_BUF_RX); + // Clear RX CTR and reserved TX CTR + ep_reg = (ep_reg & ~USB_EP_CTR_RX) | USB_EP_CTR_TX; + + if (ep_reg & USB_EP_SETUP) { + uint32_t count = btable_get_count(ep_id, BTABLE_BUF_RX); // Setup packet should always be 8 bytes. If not, ignore it, and try again. if (count == 8) { - uint16_t rx_addr = btable_get_addr(EPindex, BTABLE_BUF_RX); -#ifdef FSDEV_BUS_32BIT - dcd_event_setup_received(0, (uint8_t *)(USB_PMAADDR + rx_addr), true); -#else - // The setup_received function uses memcpy, so this must first copy the setup data into - // user memory, to allow for the 32-bit access that memcpy performs. - uint32_t userMemBuf[2]; - dcd_read_packet_memory(userMemBuf, rx_addr, 8); - dcd_event_setup_received(0, (uint8_t*) userMemBuf, true); -#endif + uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX); + uint32_t setup_packet[2]; + dcd_read_packet_memory(setup_packet, rx_addr, 8); + dcd_event_setup_received(0, (uint8_t*) setup_packet, true); // Reset EP to NAK (in case it had been stalling) - wEPRegVal = ep_add_tx_status(wEPRegVal, USB_EP_TX_NAK); - wEPRegVal = ep_add_rx_status(wEPRegVal, USB_EP_RX_NAK); - wEPRegVal = ep_add_tx_dtog(wEPRegVal, 1); - wEPRegVal = ep_add_rx_dtog(wEPRegVal, 1); - pcd_set_endpoint(USB, 0, wEPRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX); + ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK); + ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); + ep_reg = ep_add_tx_dtog(ep_reg, 1); + ep_reg = ep_add_rx_dtog(ep_reg, 1); + } else { + ep_reg &= USB_EPREG_MASK; // reversed all toggle } } else { - // Clear RX CTR interrupt flag - if (ep_addr != 0u) { - pcd_clear_rx_ep_ctr(USB, EPindex); - } + ep_reg &= USB_EPRX_STAT | USB_EPREG_MASK; // reversed all toggle except RX Status + bool const is_iso = (ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t buf_id; - if ((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { - // ISO endpoints are double buffered - buf_id = (wEPRegVal & USB_EP_DTOG_RX) ? 0 : 1; + if (is_iso) { + buf_id = (ep_reg & USB_EP_DTOG_RX) ? 0 : 1; // ISO are double buffered } else { - buf_id = 1; + buf_id = BTABLE_BUF_RX; } - uint32_t count = btable_get_count(EPindex, buf_id); - uint16_t addr = (uint16_t) btable_get_addr(EPindex, buf_id); + uint32_t rx_count = btable_get_count(ep_id, buf_id); + uint16_t pma_addr = (uint16_t) btable_get_addr(ep_id, buf_id); - if (count != 0U) { + if (rx_count != 0) { if (xfer->ff) { - dcd_read_packet_memory_ff(xfer->ff, addr, count); + dcd_read_packet_memory_ff(xfer->ff, pma_addr, rx_count); } else { - dcd_read_packet_memory(xfer->buffer + xfer->queued_len, addr, count); + dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); } - xfer->queued_len = (uint16_t)(xfer->queued_len + count); + xfer->queued_len = (uint16_t)(xfer->queued_len + rx_count); } - if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { + if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { // all bytes received or short packet dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); + + if (ep_addr == 0u) { + // prepared for status packet + btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); + } + + ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); } else { - /* Set endpoint active again for receiving more data. - * Note that isochronous endpoints stay active always */ - if ((wEPRegVal & USB_EP_TYPE_MASK) != USB_EP_ISOCHRONOUS) { - uint16_t remaining = xfer->total_len - xfer->queued_len; - uint16_t cnt = tu_min16(remaining, xfer->max_packet_size); - btable_set_rx_bufsize(EPindex, BTABLE_BUF_RX, cnt); + // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always + if (!is_iso) { + uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); + btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); } - pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); + ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_VALID); } } - // For EP0, prepare to receive another SETUP packet. - // Clear CTR last so that a new packet does not overwrite the packing being read. - // (Based on the docs, it seems SETUP will always be accepted after CTR is cleared) - if (ep_addr == 0u) { - // Always be prepared for a status packet... - btable_set_rx_bufsize(EPindex, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); - pcd_clear_rx_ep_ctr(USB, EPindex); - } + pcd_set_endpoint(USB, ep_id, ep_reg); } -static void dcd_ep_ctr_handler(void) -{ +static void dcd_ep_ctr_handler(void) { uint32_t wIstr; - /* stay in loop while pending interrupts */ while (((wIstr = USB->ISTR) & USB_ISTR_CTR) != 0U) { + uint32_t ep_id = wIstr & USB_ISTR_EP_ID; if ((wIstr & USB_ISTR_DIR) == 0U) { - /* TX/IN */ - dcd_ep_ctr_tx_handler(wIstr); + dcd_ep_ctr_tx_handler(ep_id); // TX/IN } else { - /* RX/OUT*/ - dcd_ep_ctr_rx_handler(wIstr); + dcd_ep_ctr_rx_handler(ep_id); // RX/OUT } } } @@ -609,11 +594,14 @@ void edpt0_open(uint8_t rhport) { btable_set_addr(0, BTABLE_BUF_TX, pma_addr1); uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; - ep_reg |= USB_EP_CONTROL | USB_EP_CTR_RX | USB_EP_CTR_TX; + ep_reg |= USB_EP_CONTROL; // | USB_EP_CTR_RX | USB_EP_CTR_TX; ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK); ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); // no need to explicitly set DTOG bits since we aren't masked DTOG bit + // prepare for setup packet + btable_set_rx_bufsize(0, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); + pcd_set_endpoint(USB, 0, ep_reg); } -- cgit v1.3.1 From e60efec6b71701946677440629437bedbd5bef9b Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 12:09:50 +0700 Subject: improve using ep_add_status/ep_add_dtog --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 68 +++++++++------------------ src/portable/st/stm32_fsdev/fsdev_common.h | 26 +++++----- 2 files changed, 37 insertions(+), 57 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index c7a25ba5e..c1d550ea8 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -364,10 +364,11 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { dcd_event_setup_received(0, (uint8_t*) setup_packet, true); // Reset EP to NAK (in case it had been stalling) - ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK); - ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); - ep_reg = ep_add_tx_dtog(ep_reg, 1); - ep_reg = ep_add_rx_dtog(ep_reg, 1); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_NAK); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); + + ep_reg = ep_add_dtog(ep_reg, TUSB_DIR_IN, 1); + ep_reg = ep_add_dtog(ep_reg, TUSB_DIR_OUT, 1); } else { ep_reg &= USB_EPREG_MASK; // reversed all toggle } @@ -404,15 +405,14 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { // prepared for status packet btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); } - - ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); } else { // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always if (!is_iso) { uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); } - ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_VALID); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); } } @@ -594,9 +594,9 @@ void edpt0_open(uint8_t rhport) { btable_set_addr(0, BTABLE_BUF_TX, pma_addr1); uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; - ep_reg |= USB_EP_CONTROL; // | USB_EP_CTR_RX | USB_EP_CTR_TX; - ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK); - ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); + ep_reg |= USB_EP_CONTROL; + ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_NAK); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); // no need to explicitly set DTOG bits since we aren't masked DTOG bit // prepare for setup packet @@ -637,15 +637,16 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size; xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; + ep_reg = ep_add_status(ep_reg, dir, EP_STAT_NAK); + ep_reg = ep_add_dtog(ep_reg, dir, 0); + + // reserve other direction toggle bits if (dir == TUSB_DIR_IN) { - ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK); - ep_reg = ep_add_tx_dtog(ep_reg, 0); ep_reg &= ~(USB_EPRX_STAT | USB_EP_DTOG_RX); } else { - ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); - ep_reg = ep_add_rx_dtog(ep_reg, 0); ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX); } + pcd_set_endpoint(USB, ep_idx, ep_reg); return true; @@ -669,28 +670,6 @@ void dcd_edpt_close_all(uint8_t rhport) ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE; } -/** - * Close an endpoint. - * - * This function may be called with interrupts enabled or disabled. - * - * This also clears transfers in progress, should there be any. - */ -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) -{ - (void)rhport; - - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); - uint8_t const ep_idx = xfer->ep_idx; - uint8_t const dir = tu_edpt_dir(ep_addr); - - if (dir == TUSB_DIR_IN) { - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); - } else { - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); - } -} - bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; @@ -724,15 +703,11 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX; - ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_DIS); - ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_DIS); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); - // no need to explicitly set DTOG bits since we aren't masked DTOG bit - if (dir == TUSB_DIR_IN) { - ep_reg = ep_add_rx_dtog(ep_reg, 1); - } else { - ep_reg = ep_add_tx_dtog(ep_reg, 1); - } + ep_add_dtog(ep_reg, dir, 0); + ep_add_dtog(ep_reg, 1-dir, 1); pcd_set_endpoint(USB, ep_idx, ep_reg); @@ -838,14 +813,15 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) } } -void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) -{ +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_idx = xfer->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); +// uint32_t ep_reg = pcd_get_endpoint(USB, ep_idx); + if (dir == TUSB_DIR_IN) { // IN if (pcd_get_eptype(USB, ep_idx) != USB_EP_ISOCHRONOUS) { pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 09bf4c2ca..676596c73 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -140,6 +140,10 @@ TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); #define USB_EPRX_STAT 0x3000U #endif +#ifndef USB_EPTX_STAT_Pos +#define USB_EPTX_STAT_Pos (4U) +#endif + #ifndef USB_EP_DTOG_TX_Pos #define USB_EP_DTOG_TX_Pos (6U) #endif @@ -148,6 +152,13 @@ TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); #define USB_EP_DTOG_RX_Pos (14U) #endif +typedef enum { + EP_STAT_DISABLED = 0, + EP_STAT_STALL = 1, + EP_STAT_NAK = 2, + EP_STAT_VALID = 3 +}ep_stat_t; + //--------------------------------------------------------------------+ // BTable //--------------------------------------------------------------------+ @@ -291,19 +302,12 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, pcd_set_endpoint(USBx, bEpIdx,regVal); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_status(uint32_t reg, uint32_t state) { - return reg ^ state; -} -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_status(uint32_t reg, uint32_t state) { - return reg ^ state; -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_dtog(uint32_t reg, uint32_t state) { - return reg ^ (state << USB_EP_DTOG_TX_Pos); +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) { + return reg ^ (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_dtog(uint32_t reg, uint32_t state) { - return reg ^ (state << USB_EP_DTOG_RX_Pos); +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_t dir, uint8_t state) { + return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } /** -- cgit v1.3.1 From 76cc721e8f508a02f6d4f5a1f27b24ffb9a63b7b Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 12:44:02 +0700 Subject: clean up dcd_edpt_stall/clear_statll --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 53 ++++++++----------- src/portable/st/stm32_fsdev/fsdev_common.h | 75 +++------------------------ 2 files changed, 28 insertions(+), 100 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index c1d550ea8..1d3d8cd96 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -375,7 +375,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { } else { ep_reg &= USB_EPRX_STAT | USB_EPREG_MASK; // reversed all toggle except RX Status - bool const is_iso = (ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; + bool const is_iso = ep_is_iso(ep_reg); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t buf_id; @@ -748,9 +748,8 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { dcd_int_enable(0); } -static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) -{ - (void)rhport; +static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_idx = xfer->ep_idx; @@ -762,7 +761,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) uint32_t cnt = (uint32_t) tu_min16(xfer->total_len, xfer->max_packet_size); uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx); - if ((ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { + if (ep_is_iso(ep_reg)) { btable_set_rx_bufsize(ep_idx, 0, cnt); btable_set_rx_bufsize(ep_idx, 1, cnt); } else { @@ -775,10 +774,8 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) return true; } -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) -{ +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); - xfer->buffer = buffer; xfer->ff = NULL; xfer->total_len = total_bytes; @@ -787,8 +784,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to return edpt_xfer(rhport, ep_addr); } -bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) -{ +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) { xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); xfer->buffer = NULL; xfer->ff = ff; @@ -798,19 +794,19 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t return edpt_xfer(rhport, ep_addr); } -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) -{ +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_idx = xfer->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); - if (dir == TUSB_DIR_IN) { - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_STALL); - } else { - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_STALL); - } + uint32_t ep_reg = pcd_get_endpoint(USB, ep_idx); + ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); + ep_reg = ep_add_status(ep_reg, dir, EP_STAT_STALL); + + pcd_set_endpoint(USB, ep_idx, ep_reg); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { @@ -819,23 +815,16 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_idx = xfer->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); + uint32_t ep_reg = pcd_get_endpoint(USB, ep_idx); + ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); -// uint32_t ep_reg = pcd_get_endpoint(USB, ep_idx); - - if (dir == TUSB_DIR_IN) { // IN - if (pcd_get_eptype(USB, ep_idx) != USB_EP_ISOCHRONOUS) { - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); - } - - /* Reset to DATA0 if clearing stall condition. */ - pcd_clear_tx_dtog(USB, ep_idx); - } else { // OUT - if (pcd_get_eptype(USB, ep_idx) != USB_EP_ISOCHRONOUS) { - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK); - } - /* Reset to DATA0 if clearing stall condition. */ - pcd_clear_rx_dtog(USB, ep_idx); + if (!ep_is_iso(ep_reg)) { + ep_reg = ep_add_status(ep_reg, dir, EP_STAT_NAK); } + ep_reg = ep_add_dtog(ep_reg, dir, 0); // Reset to DATA0 + + pcd_set_endpoint(USB, ep_idx, ep_reg); } #ifdef FSDEV_BUS_32BIT diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 676596c73..3b14c0334 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -159,6 +159,9 @@ typedef enum { EP_STAT_VALID = 3 }ep_stat_t; +#define EP_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) +#define EP_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) + //--------------------------------------------------------------------+ // BTable //--------------------------------------------------------------------+ @@ -274,26 +277,6 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint pcd_set_endpoint(USBx, bEpIdx, regVal); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_eptype(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EP_T_FIELD; - return regVal; -} - -/** - * @brief Clears bit CTR_RX / CTR_TX in the endpoint register. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal &= ~USB_EP_CTR_RX; - regVal |= USB_EP_CTR_TX; // preserve CTR_TX (clears on writing 0) - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPREG_MASK; @@ -310,6 +293,10 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_ return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } +TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { + return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; +} + /** * @brief sets the status for tx transfer (bits STAT_TX[1:0]). * @param USBx USB peripheral instance register address. @@ -341,54 +328,6 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx pcd_set_endpoint(USBx, bEpIdx, regVal); } -//TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) { -// uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); -// return (regVal & USB_EPRX_STAT) >> (12u); -//} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - if((regVal & USB_EP_DTOG_RX) != 0) { - pcd_rx_dtog(USBx,bEpIdx); - } -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - if((regVal & USB_EP_DTOG_TX) != 0) { - pcd_tx_dtog(USBx,bEpIdx); - } -} - -//TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { -// uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); -// regVal |= USB_EP_KIND; -// regVal &= USB_EPREG_MASK; -// regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; -// pcd_set_endpoint(USBx, bEpIdx, regVal); -//} -// -//TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { -// uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); -// regVal &= USB_EPKIND_MASK; -// regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; -// pcd_set_endpoint(USBx, bEpIdx, regVal); -//} - #ifdef __cplusplus } #endif -- cgit v1.3.1 From 8139840d7ace72be6829eb1b879747ac5352cc31 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 15:32:37 +0700 Subject: fix ep_add_dtog() --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 5 ++--- src/portable/st/stm32_fsdev/fsdev_common.h | 17 +++-------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 1d3d8cd96..6d185ced1 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -705,9 +705,8 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX; ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); - - ep_add_dtog(ep_reg, dir, 0); - ep_add_dtog(ep_reg, 1-dir, 1); + ep_reg = ep_add_dtog(ep_reg, dir, 0); + ep_reg = ep_add_dtog(ep_reg, 1-dir, 1); pcd_set_endpoint(USB, ep_idx, ep_reg); diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 3b14c0334..73dc070ed 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -254,20 +254,9 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx return FSDEV_REG->ep[bEpIdx].reg; } -/** - * @brief Sets address in an endpoint register. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @param bAddr Address. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal |= bAddr; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} +//TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value) { +// FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; +//} TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); -- cgit v1.3.1 From 3156f1c4a75e0aa7d506631a50da41ea7f38280d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 16:52:00 +0700 Subject: remove all pcd ep read, modify write --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 63 ++++++++++----------- src/portable/st/stm32_fsdev/fsdev_common.h | 79 ++++++++------------------- 2 files changed, 52 insertions(+), 90 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 6d185ced1..58de125d9 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -286,21 +286,15 @@ static void handle_bus_reset(uint8_t rhport) { // Handle CTR interrupt for the TX/IN direction static void dcd_ep_ctr_tx_handler(uint32_t ep_id) { - uint32_t wEPRegVal = pcd_get_endpoint(USB, ep_id); - uint8_t ep_addr = (wEPRegVal & USB_EPADDR_FIELD) | TUSB_DIR_IN_MASK; + uint32_t ep_reg = pcd_get_endpoint(USB, ep_id) & USB_EPREG_MASK; - // Verify the CTR_TX bit is set. This was in the ST Micro code, - // but I'm not sure it's actually necessary? - if ((wEPRegVal & USB_EP_CTR_TX) == 0U) { - return; - } - - /* clear int flag */ - pcd_clear_tx_ep_ctr(USB, ep_id); + // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? + TU_VERIFY(ep_reg & USB_EP_CTR_TX, ); + uint8_t ep_addr = (ep_reg & USB_EPADDR_FIELD) | TUSB_DIR_IN_MASK; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); - if ((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { + if (ep_is_iso(ep_reg)) { // Ignore spurious interrupts that we don't schedule // host can send IN token while there is no data to send, since ISO does not have NAK // this will result to zero length packet --> trigger interrupt (which cannot be masked) @@ -308,14 +302,19 @@ static void dcd_ep_ctr_tx_handler(uint32_t ep_id) { return; } xfer->iso_in_sending = false; - uint8_t buf_id = (wEPRegVal & USB_EP_DTOG_TX) ? 0 : 1; + uint8_t buf_id = (ep_reg & USB_EP_DTOG_TX) ? 0 : 1; btable_set_count(ep_id, buf_id, 0); } - if ((xfer->total_len != xfer->queued_len)) { - dcd_transmit_packet(xfer, ep_id); + if (xfer->total_len != xfer->queued_len) { + dcd_transmit_packet(xfer, ep_id); // also clear CTR bit } else { dcd_event_xfer_complete(0, ep_addr, xfer->total_len, XFER_RESULT_SUCCESS, true); + + // Clear CTR TX and reserved CTR RX + ep_reg = (ep_reg & ~USB_EP_CTR_TX) | USB_EP_CTR_RX; + + pcd_set_endpoint(USB, ep_id, ep_reg); } } @@ -343,15 +342,13 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { #endif uint32_t ep_reg = pcd_get_endpoint(USB, ep_id); - uint8_t ep_addr = ep_reg & USB_EPADDR_FIELD; - // Verify the CTR_RX bit is set. This was in the ST Micro code, - // but I'm not sure it's actually necessary? - if ((ep_reg & USB_EP_CTR_RX) == 0U) { - return; - } + // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? + TU_VERIFY(ep_reg & USB_EP_CTR_RX, ); - // Clear RX CTR and reserved TX CTR + uint8_t const ep_addr = ep_reg & USB_EPADDR_FIELD; + + // Clear CTR RX and reserved CTR TX ep_reg = (ep_reg & ~USB_EP_CTR_RX) | USB_EP_CTR_TX; if (ep_reg & USB_EP_SETUP) { @@ -688,8 +685,6 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet btable_set_addr(ep_idx, 1, pma_addr2); xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; - pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS); - return true; } @@ -715,13 +710,9 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) // Currently, single-buffered, and only 64 bytes at a time (max) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { - uint16_t len = (uint16_t)(xfer->total_len - xfer->queued_len); - if (len > xfer->max_packet_size) { - len = xfer->max_packet_size; - } - - uint16_t ep_reg = pcd_get_endpoint(USB, ep_ix); - bool const is_iso = (ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; + uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); + uint16_t ep_reg = pcd_get_endpoint(USB, ep_ix) | EP_CTR_TXRX; + bool const is_iso = ep_is_iso(ep_reg); uint8_t buf_id; if (is_iso) { @@ -739,8 +730,12 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { } xfer->queued_len = (uint16_t)(xfer->queued_len + len); + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_VALID); + ep_reg = ep_clear_ctr(ep_reg, TUSB_DIR_IN); + dcd_int_disable(0); - pcd_set_ep_tx_status(USB, ep_ix, USB_EP_TX_VALID); + pcd_set_endpoint(USB, ep_ix, ep_reg); if (is_iso) { xfer->iso_in_sending = true; } @@ -758,7 +753,9 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { dcd_transmit_packet(xfer, ep_idx); } else { uint32_t cnt = (uint32_t) tu_min16(xfer->total_len, xfer->max_packet_size); - uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx); + uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx) | USB_EP_CTR_TX; + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); // keep CTR TX, clear CTR RX + ep_reg = ep_add_status(ep_reg, dir, EP_STAT_VALID); if (ep_is_iso(ep_reg)) { btable_set_rx_bufsize(ep_idx, 0, cnt); @@ -767,7 +764,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); } - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_VALID); + pcd_set_endpoint(USB, ep_idx, ep_reg); } return true; diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 73dc070ed..67ee72d0e 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -141,17 +141,20 @@ TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); #endif #ifndef USB_EPTX_STAT_Pos -#define USB_EPTX_STAT_Pos (4U) +#define USB_EPTX_STAT_Pos 4u #endif #ifndef USB_EP_DTOG_TX_Pos -#define USB_EP_DTOG_TX_Pos (6U) +#define USB_EP_DTOG_TX_Pos 6u #endif -#ifndef USB_EP_DTOG_RX_Pos -#define USB_EP_DTOG_RX_Pos (14U) +#ifndef USB_EP_CTR_TX_Pos +#define USB_EP_CTR_TX_Pos 7u #endif + +#define EP_CTR_TXRX (USB_EP_CTR_TX | USB_EP_CTR_RX) + typedef enum { EP_STAT_DISABLED = 0, EP_STAT_STALL = 1, @@ -244,34 +247,23 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u // Endpoint //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) { +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t ep_id, uint32_t value) { (void) USBx; - FSDEV_REG->ep[bEpIdx].reg = (fsdev_bus_t) wRegValue; + FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; } -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) { - (void) USBx; - return FSDEV_REG->ep[bEpIdx].reg; -} - -//TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value) { +// write ep register with clear CTR_RX and CTR_TX mask (0 is no clear) +//TU_ATTR_ALWAYS_INLINE static inline void ep_write_with_clear_ctr(uint32_t ep_id, uint32_t value, uint32_t clear_ctr_mask) { +// value |= USB_EP_CTR_RX | USB_EP_CTR_TX; +// if (clear_ctr_mask) { +// value &= ~clear_ctr_mask; +// } // FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; //} -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= (uint32_t)USB_EP_T_MASK; - regVal |= wType; - regVal |= USB_EP_CTR_RX | USB_EP_CTR_TX; // These clear on write0, so must set high - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal &= ~USB_EP_CTR_TX; - regVal |= USB_EP_CTR_RX; // preserve CTR_RX (clears on writing 0) - pcd_set_endpoint(USBx, bEpIdx,regVal); +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t ep_id) { + (void) USBx; + return FSDEV_REG->ep[ep_id].reg; } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) { @@ -282,39 +274,12 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_ return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { - return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_clear_ctr(uint32_t reg, tusb_dir_t dir) { + return reg & ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -/** - * @brief sets the status for tx transfer (bits STAT_TX[1:0]). - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @param wState new state - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPTX_DTOGMASK; - regVal ^= wState; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -/** - * @brief sets the status for rx transfer (bits STAT_TX[1:0]) - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @param wState new state - * @retval None - */ - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPRX_DTOGMASK; - regVal ^= wState; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); +TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { + return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; } #ifdef __cplusplus -- cgit v1.3.1 From ee831d27ac692d33ea6240b8bce24dc98f3bf74b Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 16:53:16 +0700 Subject: rename to ep_read/write(), drop USBx argument --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 34 ++++++------ src/portable/st/stm32_fsdev/fsdev_common.h | 76 +++++++++++++-------------- 2 files changed, 54 insertions(+), 56 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 58de125d9..47b3264b1 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -227,7 +227,7 @@ void dcd_init(uint8_t rhport) { // Reset endpoints to disabled for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) { // This doesn't clear all bits since some bits are "toggle", but does set the type to DISABLED. - pcd_set_endpoint(USB, i, 0u); + ep_write(i, 0u); } USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; @@ -286,7 +286,7 @@ static void handle_bus_reset(uint8_t rhport) { // Handle CTR interrupt for the TX/IN direction static void dcd_ep_ctr_tx_handler(uint32_t ep_id) { - uint32_t ep_reg = pcd_get_endpoint(USB, ep_id) & USB_EPREG_MASK; + uint32_t ep_reg = ep_read(ep_id) & USB_EPREG_MASK; // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? TU_VERIFY(ep_reg & USB_EP_CTR_TX, ); @@ -314,7 +314,7 @@ static void dcd_ep_ctr_tx_handler(uint32_t ep_id) { // Clear CTR TX and reserved CTR RX ep_reg = (ep_reg & ~USB_EP_CTR_TX) | USB_EP_CTR_RX; - pcd_set_endpoint(USB, ep_id, ep_reg); + ep_write(ep_id, ep_reg); } } @@ -341,7 +341,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { } #endif - uint32_t ep_reg = pcd_get_endpoint(USB, ep_id); + uint32_t ep_reg = ep_read(ep_id); // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? TU_VERIFY(ep_reg & USB_EP_CTR_RX, ); @@ -413,7 +413,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { } } - pcd_set_endpoint(USB, ep_id, ep_reg); + ep_write(ep_id, ep_reg); } static void dcd_ep_ctr_handler(void) { @@ -599,7 +599,7 @@ void edpt0_open(uint8_t rhport) { // prepare for setup packet btable_set_rx_bufsize(0, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); - pcd_set_endpoint(USB, 0, ep_reg); + ep_write(0, ep_reg); } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { @@ -644,7 +644,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX); } - pcd_set_endpoint(USB, ep_idx, ep_reg); + ep_write(ep_idx, ep_reg); return true; } @@ -655,7 +655,7 @@ void dcd_edpt_close_all(uint8_t rhport) for (uint32_t i = 1; i < FSDEV_EP_COUNT; i++) { // Reset endpoint - pcd_set_endpoint(USB, i, 0); + ep_write(i, 0); // Clear EP allocation status ep_alloc_status[i].ep_num = 0xFF; ep_alloc_status[i].ep_type = 0xFF; @@ -703,7 +703,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) ep_reg = ep_add_dtog(ep_reg, dir, 0); ep_reg = ep_add_dtog(ep_reg, 1-dir, 1); - pcd_set_endpoint(USB, ep_idx, ep_reg); + ep_write(ep_idx, ep_reg); return true; } @@ -711,7 +711,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) // Currently, single-buffered, and only 64 bytes at a time (max) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); - uint16_t ep_reg = pcd_get_endpoint(USB, ep_ix) | EP_CTR_TXRX; + uint16_t ep_reg = ep_read(ep_ix) | EP_CTR_TXRX; bool const is_iso = ep_is_iso(ep_reg); uint8_t buf_id; @@ -735,7 +735,7 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { ep_reg = ep_clear_ctr(ep_reg, TUSB_DIR_IN); dcd_int_disable(0); - pcd_set_endpoint(USB, ep_ix, ep_reg); + ep_write(ep_ix, ep_reg); if (is_iso) { xfer->iso_in_sending = true; } @@ -753,7 +753,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { dcd_transmit_packet(xfer, ep_idx); } else { uint32_t cnt = (uint32_t) tu_min16(xfer->total_len, xfer->max_packet_size); - uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx) | USB_EP_CTR_TX; + uint16_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX; ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); // keep CTR TX, clear CTR RX ep_reg = ep_add_status(ep_reg, dir, EP_STAT_VALID); @@ -764,7 +764,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); } - pcd_set_endpoint(USB, ep_idx, ep_reg); + ep_write(ep_idx, ep_reg); } return true; @@ -797,12 +797,12 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { uint8_t const ep_idx = xfer->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); - uint32_t ep_reg = pcd_get_endpoint(USB, ep_idx); + uint32_t ep_reg = ep_read(ep_idx); ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); ep_reg = ep_add_status(ep_reg, dir, EP_STAT_STALL); - pcd_set_endpoint(USB, ep_idx, ep_reg); + ep_write(ep_idx, ep_reg); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { @@ -811,7 +811,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_idx = xfer->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); - uint32_t ep_reg = pcd_get_endpoint(USB, ep_idx); + uint32_t ep_reg = ep_read(ep_idx); ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); @@ -820,7 +820,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { } ep_reg = ep_add_dtog(ep_reg, dir, 0); // Reset to DATA0 - pcd_set_endpoint(USB, ep_idx, ep_reg); + ep_write(ep_idx, ep_reg); } #ifdef FSDEV_BUS_32BIT diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 67ee72d0e..4ada26895 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -165,6 +165,43 @@ typedef enum { #define EP_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) #define EP_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) +//--------------------------------------------------------------------+ +// Endpoint +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value) { + FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; +} + +// write ep register with clear CTR_RX and CTR_TX mask (0 is no clear) +//TU_ATTR_ALWAYS_INLINE static inline void ep_write_with_clear_ctr(uint32_t ep_id, uint32_t value, uint32_t clear_ctr_mask) { +// value |= USB_EP_CTR_RX | USB_EP_CTR_TX; +// if (clear_ctr_mask) { +// value &= ~clear_ctr_mask; +// } +// FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; +//} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { + return FSDEV_REG->ep[ep_id].reg; +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) { + return reg ^ (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_t dir, uint8_t state) { + return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_clear_ctr(uint32_t reg, tusb_dir_t dir) { + return reg & ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +} + +TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { + return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; +} + //--------------------------------------------------------------------+ // BTable //--------------------------------------------------------------------+ @@ -243,45 +280,6 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u #endif } -//--------------------------------------------------------------------+ -// Endpoint -//--------------------------------------------------------------------+ - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t ep_id, uint32_t value) { - (void) USBx; - FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; -} - -// write ep register with clear CTR_RX and CTR_TX mask (0 is no clear) -//TU_ATTR_ALWAYS_INLINE static inline void ep_write_with_clear_ctr(uint32_t ep_id, uint32_t value, uint32_t clear_ctr_mask) { -// value |= USB_EP_CTR_RX | USB_EP_CTR_TX; -// if (clear_ctr_mask) { -// value &= ~clear_ctr_mask; -// } -// FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; -//} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t ep_id) { - (void) USBx; - return FSDEV_REG->ep[ep_id].reg; -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) { - return reg ^ (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_t dir, uint8_t state) { - return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_clear_ctr(uint32_t reg, tusb_dir_t dir) { - return reg & ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); -} - -TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { - return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; -} - #ifdef __cplusplus } #endif -- cgit v1.3.1 From ce0fdc56097efda926c2c3776eec345c920b6cc6 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 17:10:43 +0700 Subject: refactor dcd_ep_ctr_handler --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 37 +++++++++++---------------- src/portable/st/stm32_fsdev/fsdev_common.h | 2 ++ 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 47b3264b1..381dfdd94 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -166,7 +166,6 @@ static uint8_t remoteWakeCountdown; // When wake is requested static void handle_bus_reset(uint8_t rhport); static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix); static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr); -static void dcd_ep_ctr_handler(void); // PMA allocation/access static uint16_t ep_buf_ptr; ///< Points to first free memory location @@ -285,7 +284,7 @@ static void handle_bus_reset(uint8_t rhport) { } // Handle CTR interrupt for the TX/IN direction -static void dcd_ep_ctr_tx_handler(uint32_t ep_id) { +static void handle_ctr_tx(uint32_t ep_id) { uint32_t ep_reg = ep_read(ep_id) & USB_EPREG_MASK; // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? @@ -319,7 +318,7 @@ static void dcd_ep_ctr_tx_handler(uint32_t ep_id) { } // Handle CTR interrupt for the RX/OUT direction -static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { +static void handle_ctr_rx(uint32_t ep_id) { #ifdef FSDEV_BUS_32BIT /* https://www.st.com/resource/en/errata_sheet/es0561-stm32h503cbebkbrb-device-errata-stmicroelectronics.pdf * From STM32H503 errata 2.15.1: Buffer description table update completes after CTR interrupt triggers @@ -416,19 +415,6 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { ep_write(ep_id, ep_reg); } -static void dcd_ep_ctr_handler(void) { - uint32_t wIstr; - /* stay in loop while pending interrupts */ - while (((wIstr = USB->ISTR) & USB_ISTR_CTR) != 0U) { - uint32_t ep_id = wIstr & USB_ISTR_EP_ID; - if ((wIstr & USB_ISTR_DIR) == 0U) { - dcd_ep_ctr_tx_handler(ep_id); // TX/IN - } else { - dcd_ep_ctr_rx_handler(ep_id); // RX/OUT - } - } -} - void dcd_int_handler(uint8_t rhport) { uint32_t int_status = USB->ISTR; // const uint32_t handled_ints = USB_ISTR_CTR | USB_ISTR_RESET | USB_ISTR_WKUP @@ -453,12 +439,6 @@ void dcd_int_handler(uint8_t rhport) { return; // Don't do the rest of the things here; perhaps they've been cleared? } - if (int_status & USB_ISTR_CTR) { - /* servicing of the endpoint correct transfer interrupt */ - /* clear of the CTR flag into the sub */ - dcd_ep_ctr_handler(); - } - if (int_status & USB_ISTR_WKUP) { USB->CNTR &= ~USB_CNTR_LPMODE; USB->CNTR &= ~USB_CNTR_FSUSP; @@ -489,6 +469,19 @@ void dcd_int_handler(uint8_t rhport) { } USB->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF; } + + // loop to handle all pending CTR interrupts + while (int_status & USB_ISTR_CTR) { + uint32_t const ep_id = int_status & USB_ISTR_EP_ID; + + if ((int_status & USB_ISTR_DIR) == 0U) { + handle_ctr_tx(ep_id); // TX/IN + } else { + handle_ctr_rx(ep_id); // RX/OUT or both (RX/TX !!) + } + + int_status = USB->ISTR; + } } //--------------------------------------------------------------------+ diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 4ada26895..dd030652b 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -167,6 +167,8 @@ typedef enum { //--------------------------------------------------------------------+ // Endpoint +// - CTR is write 0 to clear +// - DTOG and STAT are write 1 to toggle //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value) { -- cgit v1.3.1 From 26b0df2c26d31eef1a0d4012d42534f9c434f4eb Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 17:24:41 +0700 Subject: refactor xfer_ctl_ptr() to take epnum/dir to reduce computation --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 77 +++++++++++++++------------ 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 381dfdd94..d0a51d48e 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -165,7 +165,7 @@ static uint8_t remoteWakeCountdown; // When wake is requested // into the stack. static void handle_bus_reset(uint8_t rhport); static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix); -static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr); +static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir); // PMA allocation/access static uint16_t ep_buf_ptr; ///< Points to first free memory location @@ -183,13 +183,7 @@ static void edpt0_open(uint8_t rhport); // Inline helper //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint32_t ep_addr) -{ - uint8_t epnum = tu_edpt_number(ep_addr); - uint8_t dir = tu_edpt_dir(ep_addr); - // Fix -Werror=null-dereference - TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX, &xfer_status[0][0]); - +TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint8_t epnum, uint8_t dir) { return &xfer_status[epnum][dir]; } @@ -290,8 +284,9 @@ static void handle_ctr_tx(uint32_t ep_id) { // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? TU_VERIFY(ep_reg & USB_EP_CTR_TX, ); + uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD; uint8_t ep_addr = (ep_reg & USB_EPADDR_FIELD) | TUSB_DIR_IN_MASK; - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_IN); if (ep_is_iso(ep_reg)) { // Ignore spurious interrupts that we don't schedule @@ -344,11 +339,9 @@ static void handle_ctr_rx(uint32_t ep_id) { // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? TU_VERIFY(ep_reg & USB_EP_CTR_RX, ); + ep_reg = (ep_reg & ~USB_EP_CTR_RX) | USB_EP_CTR_TX; // Clear CTR RX and reserved CTR TX - uint8_t const ep_addr = ep_reg & USB_EPADDR_FIELD; - - // Clear CTR RX and reserved CTR TX - ep_reg = (ep_reg & ~USB_EP_CTR_RX) | USB_EP_CTR_TX; + uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD; if (ep_reg & USB_EP_SETUP) { uint32_t count = btable_get_count(ep_id, BTABLE_BUF_RX); @@ -372,7 +365,7 @@ static void handle_ctr_rx(uint32_t ep_id) { ep_reg &= USB_EPRX_STAT | USB_EPREG_MASK; // reversed all toggle except RX Status bool const is_iso = ep_is_iso(ep_reg); - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT); uint8_t buf_id; if (is_iso) { @@ -394,10 +387,11 @@ static void handle_ctr_rx(uint32_t ep_id) { } if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { + uint8_t const ep_addr = ep_num; // all bytes received or short packet dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); - if (ep_addr == 0u) { + if (ep_num == 0) { // prepared for status packet btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); } @@ -598,6 +592,7 @@ void edpt0_open(uint8_t rhport) { bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void)rhport; uint8_t const ep_addr = desc_ep->bEndpointAddress; + uint8_t const ep_num = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); const uint16_t packet_size = tu_edpt_packet_size(desc_ep); uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); @@ -624,8 +619,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { uint16_t pma_addr = dcd_pma_alloc(packet_size, false); btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr); - xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size; - xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); + xfer->max_packet_size = packet_size; + xfer->ep_idx = ep_idx; ep_reg = ep_add_status(ep_reg, dir, EP_STAT_NAK); ep_reg = ep_add_dtog(ep_reg, dir, 0); @@ -663,6 +659,8 @@ void dcd_edpt_close_all(uint8_t rhport) bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; + uint8_t const ep_num = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); uint8_t const ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS); /* Create a packet memory buffer area. Enable double buffering for devices with 2048 bytes PMA, @@ -676,7 +674,9 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet btable_set_addr(ep_idx, 0, pma_addr); btable_set_addr(ep_idx, 1, pma_addr2); - xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; + + xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir); + xfer->ep_idx = ep_idx; return true; } @@ -684,10 +684,13 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void)rhport; uint8_t const ep_addr = desc_ep->bEndpointAddress; - uint8_t const ep_idx = xfer_ctl_ptr(ep_addr)->ep_idx; + uint8_t const ep_num = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); + xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir); - xfer_ctl_ptr(ep_addr)->max_packet_size = tu_edpt_packet_size(desc_ep); + uint8_t const ep_idx = xfer->ep_idx; + + xfer->max_packet_size = tu_edpt_packet_size(desc_ep); uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX; @@ -735,12 +738,11 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { dcd_int_enable(0); } -static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { +static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { (void) rhport; - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); uint8_t const ep_idx = xfer->ep_idx; - uint8_t const dir = tu_edpt_dir(ep_addr); if (dir == TUSB_DIR_IN) { dcd_transmit_packet(xfer, ep_idx); @@ -764,31 +766,37 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + uint8_t const ep_num = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); + xfer->buffer = buffer; xfer->ff = NULL; xfer->total_len = total_bytes; xfer->queued_len = 0; - return edpt_xfer(rhport, ep_addr); + return edpt_xfer(rhport, ep_num, dir); } bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) { - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + uint8_t const ep_num = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); + xfer->buffer = NULL; xfer->ff = ff; xfer->total_len = total_bytes; xfer->queued_len = 0; - return edpt_xfer(rhport, ep_addr); + return edpt_xfer(rhport, ep_num, dir); } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; - - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); - uint8_t const ep_idx = xfer->ep_idx; + uint8_t const ep_num = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); + uint8_t const ep_idx = xfer->ep_idx; uint32_t ep_reg = ep_read(ep_idx); ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits @@ -801,11 +809,12 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); - uint8_t const ep_idx = xfer->ep_idx; + uint8_t const ep_num = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - uint32_t ep_reg = ep_read(ep_idx); - ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); + uint8_t const ep_idx = xfer->ep_idx; + + uint32_t ep_reg = ep_read(ep_idx) | EP_CTR_TXRX; ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); if (!ep_is_iso(ep_reg)) { -- cgit v1.3.1 From 7954d9cb4c486b263bed8984b7dd7553092150f9 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 18:15:22 +0700 Subject: rename to fsdev_type.h, use FSDDEV_REG instead of USB --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 57 ++--- src/portable/st/stm32_fsdev/fsdev_common.h | 289 -------------------------- src/portable/st/stm32_fsdev/fsdev_stm32.h | 2 + src/portable/st/stm32_fsdev/fsdev_type.h | 286 +++++++++++++++++++++++++ 4 files changed, 317 insertions(+), 317 deletions(-) delete mode 100644 src/portable/st/stm32_fsdev/fsdev_common.h create mode 100644 src/portable/st/stm32_fsdev/fsdev_type.h diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index d0a51d48e..29e1ca111 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -123,7 +123,7 @@ #error "Unknown USB IP" #endif -#include "fsdev_common.h" +#include "fsdev_type.h" //--------------------------------------------------------------------+ // Configuration @@ -197,25 +197,25 @@ void dcd_init(uint8_t rhport) { } // Perform USB peripheral reset - USB->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; + FSDEV_REG->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } - USB->CNTR &= ~USB_CNTR_PDWN; + FSDEV_REG->CNTR &= ~USB_CNTR_PDWN; // Wait startup time, for F042 and F070, this is <= 1 us. for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } - USB->CNTR = 0; // Enable USB + FSDEV_REG->CNTR = 0; // Enable USB -#if !defined(STM32G0) && !defined(STM32H5) && !defined(STM32U5) - // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address - USB->BTABLE = FSDEV_BTABLE_BASE; +#if !defined(FSDEV_BUS_32BIT) + // BTABLE register does not exist any more on 32-bit bus devices + FSDEV_REG->BTABLE = FSDEV_BTABLE_BASE; #endif - USB->ISTR = 0; // Clear pending interrupts + FSDEV_REG->ISTR = 0; // Clear pending interrupts // Reset endpoints to disabled for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) { @@ -223,7 +223,7 @@ void dcd_init(uint8_t rhport) { ep_write(i, 0u); } - USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; + FSDEV_REG->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; handle_bus_reset(rhport); // Enable pull-up if supported @@ -234,9 +234,9 @@ void dcd_sof_enable(uint8_t rhport, bool en) { (void)rhport; if (en) { - USB->CNTR |= USB_CNTR_SOFM; + FSDEV_REG->CNTR |= USB_CNTR_SOFM; } else { - USB->CNTR &= ~USB_CNTR_SOFM; + FSDEV_REG->CNTR &= ~USB_CNTR_SOFM; } } @@ -254,12 +254,12 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { void dcd_remote_wakeup(uint8_t rhport) { (void)rhport; - USB->CNTR |= USB_CNTR_RESUME; + FSDEV_REG->CNTR |= USB_CNTR_RESUME; remoteWakeCountdown = 4u; // required to be 1 to 15 ms, ESOF should trigger every 1ms. } static void handle_bus_reset(uint8_t rhport) { - USB->DADDR = 0u; // disable USB Function + FSDEV_REG->DADDR = 0u; // disable USB Function for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) { // Clear EP allocation status @@ -274,7 +274,7 @@ static void handle_bus_reset(uint8_t rhport) { edpt0_open(rhport); // open control endpoint (both IN & OUT) - USB->DADDR = USB_DADDR_EF; // Enable USB Function + FSDEV_REG->DADDR = USB_DADDR_EF; // Enable USB Function } // Handle CTR interrupt for the TX/IN direction @@ -410,7 +410,7 @@ static void handle_ctr_rx(uint32_t ep_id) { } void dcd_int_handler(uint8_t rhport) { - uint32_t int_status = USB->ISTR; + uint32_t int_status = FSDEV_REG->ISTR; // const uint32_t handled_ints = USB_ISTR_CTR | USB_ISTR_RESET | USB_ISTR_WKUP // | USB_ISTR_SUSP | USB_ISTR_SOF | USB_ISTR_ESOF; // unused IRQs: (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_L1REQ ) @@ -421,23 +421,23 @@ void dcd_int_handler(uint8_t rhport) { /* Put SOF flag at the beginning of ISR in case to get least amount of jitter if it is used for timing purposes */ if (int_status & USB_ISTR_SOF) { - USB->ISTR = (fsdev_bus_t)~USB_ISTR_SOF; - dcd_event_sof(0, USB->FNR & USB_FNR_FN, true); + FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_SOF; + dcd_event_sof(0, FSDEV_REG->FNR & USB_FNR_FN, true); } if (int_status & USB_ISTR_RESET) { // USBRST is start of reset. - USB->ISTR = (fsdev_bus_t)~USB_ISTR_RESET; + FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_RESET; handle_bus_reset(rhport); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); return; // Don't do the rest of the things here; perhaps they've been cleared? } if (int_status & USB_ISTR_WKUP) { - USB->CNTR &= ~USB_CNTR_LPMODE; - USB->CNTR &= ~USB_CNTR_FSUSP; + FSDEV_REG->CNTR &= ~USB_CNTR_LPMODE; + FSDEV_REG->CNTR &= ~USB_CNTR_FSUSP; - USB->ISTR = (fsdev_bus_t)~USB_ISTR_WKUP; + FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_WKUP; dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } @@ -446,22 +446,22 @@ void dcd_int_handler(uint8_t rhport) { * these events cannot be differentiated, so we only trigger suspend. */ /* Force low-power mode in the macrocell */ - USB->CNTR |= USB_CNTR_FSUSP; - USB->CNTR |= USB_CNTR_LPMODE; + FSDEV_REG->CNTR |= USB_CNTR_FSUSP; + FSDEV_REG->CNTR |= USB_CNTR_LPMODE; /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ - USB->ISTR = (fsdev_bus_t)~USB_ISTR_SUSP; + FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_SUSP; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } if (int_status & USB_ISTR_ESOF) { if (remoteWakeCountdown == 1u) { - USB->CNTR &= ~USB_CNTR_RESUME; + FSDEV_REG->CNTR &= ~USB_CNTR_RESUME; } if (remoteWakeCountdown > 0u) { remoteWakeCountdown--; } - USB->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF; + FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF; } // loop to handle all pending CTR interrupts @@ -474,7 +474,7 @@ void dcd_int_handler(uint8_t rhport) { handle_ctr_rx(ep_id); // RX/OUT or both (RX/TX !!) } - int_status = USB->ISTR; + int_status = FSDEV_REG->ISTR; } } @@ -488,10 +488,11 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *req (void)rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) { uint8_t const dev_addr = (uint8_t)request->wValue; - USB->DADDR = (USB_DADDR_EF | dev_addr); + FSDEV_REG->DADDR = (USB_DADDR_EF | dev_addr); } } diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h deleted file mode 100644 index dd030652b..000000000 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ /dev/null @@ -1,289 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright(c) 2016 STMicroelectronics - * Copyright(c) N Conrad - * Copyright (c) 2024, hathach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -#ifndef TUSB_FSDEV_COMMON_H -#define TUSB_FSDEV_COMMON_H - -#ifdef __cplusplus - extern "C" { -#endif - -#include "stdint.h" - -// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it -// Both of these MUST be a multiple of 2, and are in byte units. -#ifndef FSDEV_BTABLE_BASE -#define FSDEV_BTABLE_BASE 0U -#endif - -TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 bytes"); - -// FSDEV_PMA_SIZE is PMA buffer size in bytes. -// - 512-byte devices, access with a stride of two words (use every other 16-bit address) -// - 1024-byte devices, access with a stride of one word (use every 16-bit address) -// - 2048-byte devices, access with 32-bit address - -// For purposes of accessing the packet -#if FSDEV_PMA_SIZE == 512 - #define FSDEV_PMA_STRIDE (2u) // 1x16 bit access scheme - #define pma_aligned TU_ATTR_ALIGNED(4) -#elif FSDEV_PMA_SIZE == 1024 - #define FSDEV_PMA_STRIDE (1u) // 2x16 bit access scheme - #define pma_aligned -#elif FSDEV_PMA_SIZE == 2048 - #ifndef FSDEV_BUS_32BIT - #warning "FSDEV_PMA_SIZE is 2048, but FSDEV_BUS_32BIT is not defined" - #endif - #define FSDEV_PMA_STRIDE (1u) // 32 bit access scheme - #define pma_aligned -#endif - -enum { - BTABLE_BUF_TX = 0, - BTABLE_BUF_RX = 1 -}; - -// hardware limit endpoint -#define FSDEV_EP_COUNT 8 - -// Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either -// 16-bit or 32-bit depending on FSDEV_BUS_32BIT. -typedef struct { - union { - // 0: TX (IN), 1: RX (OUT) - - // strictly 16-bit access (could be 32-bit aligned) - struct { - volatile pma_aligned uint16_t addr; - volatile pma_aligned uint16_t count; - } ep16[FSDEV_EP_COUNT][2]; - - // strictly 32-bit access - struct { - volatile uint32_t count_addr; - } ep32[FSDEV_EP_COUNT][2]; - }; -} fsdev_btable_t; - -TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT*8*FSDEV_PMA_STRIDE, "size is not correct"); -TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM"); - - -#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) - -// volatile 32-bit aligned -#define _va32 volatile TU_ATTR_ALIGNED(4) - -// The fsdev_bus_t type can be used for both register and PMA access necessities -// For type-safety create a new macro for the volatile address of PMAADDR -// The compiler should warn us if we cast it to a non-volatile type? -#ifdef FSDEV_BUS_32BIT -typedef uint32_t fsdev_bus_t; -static volatile uint32_t * const pma32 = (volatile uint32_t*)USB_PMAADDR; - -#else -typedef uint16_t fsdev_bus_t; -// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) -static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; -#endif - -typedef struct { - struct { - _va32 fsdev_bus_t reg; - }ep[FSDEV_EP_COUNT]; - - _va32 uint32_t RESERVED7[8]; // Reserved - _va32 fsdev_bus_t CNTR; // 40: Control register - _va32 fsdev_bus_t ISTR; // 44: Interrupt status register - _va32 fsdev_bus_t FNR; // 48: Frame number register - _va32 fsdev_bus_t DADDR; // 4C: Device address register - _va32 fsdev_bus_t BTABLE; // 50: Buffer Table address register (16-bit only) - _va32 fsdev_bus_t LPMCSR; // 54: LPM Control and Status Register (32-bit only) - _va32 fsdev_bus_t BCDR; // 58: Battery Charging Detector Register (32-bit only) -} fsdev_regs_t; - -TU_VERIFY_STATIC(offsetof(fsdev_regs_t, CNTR) == 0x40, "Wrong offset"); -TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); - -#define FSDEV_REG ((fsdev_regs_t*) FSDEV_REG_BASE) - - -#ifndef USB_EPTX_STAT -#define USB_EPTX_STAT 0x0030U -#endif - -#ifndef USB_EPRX_STAT -#define USB_EPRX_STAT 0x3000U -#endif - -#ifndef USB_EPTX_STAT_Pos -#define USB_EPTX_STAT_Pos 4u -#endif - -#ifndef USB_EP_DTOG_TX_Pos -#define USB_EP_DTOG_TX_Pos 6u -#endif - -#ifndef USB_EP_CTR_TX_Pos -#define USB_EP_CTR_TX_Pos 7u -#endif - - -#define EP_CTR_TXRX (USB_EP_CTR_TX | USB_EP_CTR_RX) - -typedef enum { - EP_STAT_DISABLED = 0, - EP_STAT_STALL = 1, - EP_STAT_NAK = 2, - EP_STAT_VALID = 3 -}ep_stat_t; - -#define EP_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) -#define EP_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) - -//--------------------------------------------------------------------+ -// Endpoint -// - CTR is write 0 to clear -// - DTOG and STAT are write 1 to toggle -//--------------------------------------------------------------------+ - -TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value) { - FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; -} - -// write ep register with clear CTR_RX and CTR_TX mask (0 is no clear) -//TU_ATTR_ALWAYS_INLINE static inline void ep_write_with_clear_ctr(uint32_t ep_id, uint32_t value, uint32_t clear_ctr_mask) { -// value |= USB_EP_CTR_RX | USB_EP_CTR_TX; -// if (clear_ctr_mask) { -// value &= ~clear_ctr_mask; -// } -// FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; -//} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { - return FSDEV_REG->ep[ep_id].reg; -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) { - return reg ^ (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_t dir, uint8_t state) { - return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_clear_ctr(uint32_t reg, tusb_dir_t dir) { - return reg & ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); -} - -TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { - return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; -} - -//--------------------------------------------------------------------+ -// BTable -//--------------------------------------------------------------------+ - -TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) { -#ifdef FSDEV_BUS_32BIT - return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu; -#else - return FSDEV_BTABLE->ep16[ep_id][buf_id].addr; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) { -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; - count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); - FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; -#else - FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { - uint16_t count; -#ifdef FSDEV_BUS_32BIT - count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16); -#else - count = FSDEV_BTABLE->ep16[ep_id][buf_id].count; -#endif - return count & 0x3FFU; -} - -TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) { -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; - count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16); - FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; -#else - uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count; - cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU); - FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt; -#endif -} - -/* Aligned buffer size according to hardware */ -TU_ATTR_ALWAYS_INLINE static inline uint16_t pma_align_buffer_size(uint16_t size, uint8_t* blsize, uint8_t* num_block) { - /* The STM32 full speed USB peripheral supports only a limited set of - * buffer sizes given by the RX buffer entry format in the USB_BTABLE. */ - uint16_t block_in_bytes; - if (size > 62) { - block_in_bytes = 32; - *blsize = 1; - } else { - block_in_bytes = 2; - *blsize = 0; - } - - *num_block = tu_div_ceil(size, block_in_bytes); - - return (*num_block) * block_in_bytes; -} - -TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint32_t wCount) { - uint8_t blsize, num_block; - (void) pma_align_buffer_size(wCount, &blsize, &num_block); - - /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ - uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10); - -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; - count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu); - FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; -#else - FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb; -#endif -} - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index f20505f28..bb2c72fd1 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -198,6 +198,8 @@ #define FSDEV_REG_BASE USB_BASE #elif defined(USB_DRD_BASE) #define FSDEV_REG_BASE USB_DRD_BASE +#elif defined(USB_DRD_FS_BASE) + #define FSDEV_REG_BASE USB_DRD_FS_BASE #else #error "FSDEV_REG_BASE not defined" #endif diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h new file mode 100644 index 000000000..116017f63 --- /dev/null +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -0,0 +1,286 @@ +/* + * The MIT License (MIT) + * + * Copyright(c) 2016 STMicroelectronics + * Copyright(c) N Conrad + * Copyright (c) 2024, hathach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef TUSB_FSDEV_TYPE_H +#define TUSB_FSDEV_TYPE_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "stdint.h" + +// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it +// Both of these MUST be a multiple of 2, and are in byte units. +#ifndef FSDEV_BTABLE_BASE +#define FSDEV_BTABLE_BASE 0U +#endif + +TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 bytes"); + +// FSDEV_PMA_SIZE is PMA buffer size in bytes. +// - 512-byte devices, access with a stride of two words (use every other 16-bit address) +// - 1024-byte devices, access with a stride of one word (use every 16-bit address) +// - 2048-byte devices, access with 32-bit address + +// For purposes of accessing the packet +#if FSDEV_PMA_SIZE == 512 + #define FSDEV_PMA_STRIDE (2u) // 1x16 bit access scheme + #define pma_aligned TU_ATTR_ALIGNED(4) +#elif FSDEV_PMA_SIZE == 1024 + #define FSDEV_PMA_STRIDE (1u) // 2x16 bit access scheme + #define pma_aligned +#elif FSDEV_PMA_SIZE == 2048 + #ifndef FSDEV_BUS_32BIT + #warning "FSDEV_PMA_SIZE is 2048, but FSDEV_BUS_32BIT is not defined" + #endif + #define FSDEV_PMA_STRIDE (1u) // 32 bit access scheme + #define pma_aligned +#endif + +//--------------------------------------------------------------------+ +// BTable Typedef +//--------------------------------------------------------------------+ +enum { + BTABLE_BUF_TX = 0, + BTABLE_BUF_RX = 1 +}; + +// hardware limit endpoint +#define FSDEV_EP_COUNT 8 + +// Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either +// 16-bit or 32-bit depending on FSDEV_BUS_32BIT. +typedef struct { + union { + // 0: TX (IN), 1: RX (OUT) + + // strictly 16-bit access (could be 32-bit aligned) + struct { + volatile pma_aligned uint16_t addr; + volatile pma_aligned uint16_t count; + } ep16[FSDEV_EP_COUNT][2]; + + // strictly 32-bit access + struct { + volatile uint32_t count_addr; + } ep32[FSDEV_EP_COUNT][2]; + }; +} fsdev_btable_t; + +TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT*8*FSDEV_PMA_STRIDE, "size is not correct"); +TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM"); + +#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) + +//--------------------------------------------------------------------+ +// Registers Typedef +//--------------------------------------------------------------------+ + +// volatile 32-bit aligned +#define _va32 volatile TU_ATTR_ALIGNED(4) + +// The fsdev_bus_t type can be used for both register and PMA access necessities +// For type-safety create a new macro for the volatile address of PMAADDR +// The compiler should warn us if we cast it to a non-volatile type? +#ifdef FSDEV_BUS_32BIT +typedef uint32_t fsdev_bus_t; +static volatile uint32_t * const pma32 = (volatile uint32_t*)USB_PMAADDR; + +#else +typedef uint16_t fsdev_bus_t; +// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) +static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; +#endif + +typedef struct { + struct { + _va32 fsdev_bus_t reg; + }ep[FSDEV_EP_COUNT]; + + _va32 uint32_t RESERVED7[8]; // Reserved + _va32 fsdev_bus_t CNTR; // 40: Control register + _va32 fsdev_bus_t ISTR; // 44: Interrupt status register + _va32 fsdev_bus_t FNR; // 48: Frame number register + _va32 fsdev_bus_t DADDR; // 4C: Device address register + _va32 fsdev_bus_t BTABLE; // 50: Buffer Table address register (16-bit only) + _va32 fsdev_bus_t LPMCSR; // 54: LPM Control and Status Register (32-bit only) + _va32 fsdev_bus_t BCDR; // 58: Battery Charging Detector Register (32-bit only) +} fsdev_regs_t; + +TU_VERIFY_STATIC(offsetof(fsdev_regs_t, CNTR) == 0x40, "Wrong offset"); +TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); + +#define FSDEV_REG ((fsdev_regs_t*) FSDEV_REG_BASE) + + +#ifndef USB_EPTX_STAT +#define USB_EPTX_STAT 0x0030U +#endif + +#ifndef USB_EPRX_STAT +#define USB_EPRX_STAT 0x3000U +#endif + +#ifndef USB_EPTX_STAT_Pos +#define USB_EPTX_STAT_Pos 4u +#endif + +#ifndef USB_EP_DTOG_TX_Pos +#define USB_EP_DTOG_TX_Pos 6u +#endif + +#ifndef USB_EP_CTR_TX_Pos +#define USB_EP_CTR_TX_Pos 7u +#endif + + +#define EP_CTR_TXRX (USB_EP_CTR_TX | USB_EP_CTR_RX) + +typedef enum { + EP_STAT_DISABLED = 0, + EP_STAT_STALL = 1, + EP_STAT_NAK = 2, + EP_STAT_VALID = 3 +}ep_stat_t; + +#define EP_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) +#define EP_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) + +//--------------------------------------------------------------------+ +// Endpoint Helper +// - CTR is write 0 to clear +// - DTOG and STAT are write 1 to toggle +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value) { + FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { + return FSDEV_REG->ep[ep_id].reg; +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) { + return reg ^ (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_t dir, uint8_t state) { + return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_clear_ctr(uint32_t reg, tusb_dir_t dir) { + return reg & ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +} + +TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { + return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; +} + +//--------------------------------------------------------------------+ +// BTable Helper +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) { +#ifdef FSDEV_BUS_32BIT + return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu; +#else + return FSDEV_BTABLE->ep16[ep_id][buf_id].addr; +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) { +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; +#else + FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr; +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { + uint16_t count; +#ifdef FSDEV_BUS_32BIT + count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16); +#else + count = FSDEV_BTABLE->ep16[ep_id][buf_id].count; +#endif + return count & 0x3FFU; +} + +TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) { +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; +#else + uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count; + cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU); + FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt; +#endif +} + +/* Aligned buffer size according to hardware */ +TU_ATTR_ALWAYS_INLINE static inline uint16_t pma_align_buffer_size(uint16_t size, uint8_t* blsize, uint8_t* num_block) { + /* The STM32 full speed USB peripheral supports only a limited set of + * buffer sizes given by the RX buffer entry format in the USB_BTABLE. */ + uint16_t block_in_bytes; + if (size > 62) { + block_in_bytes = 32; + *blsize = 1; + } else { + block_in_bytes = 2; + *blsize = 0; + } + + *num_block = tu_div_ceil(size, block_in_bytes); + + return (*num_block) * block_in_bytes; +} + +TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint32_t wCount) { + uint8_t blsize, num_block; + (void) pma_align_buffer_size(wCount, &blsize, &num_block); + + /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ + uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10); + +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; +#else + FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb; +#endif +} + +#ifdef __cplusplus + } +#endif + +#endif -- cgit v1.3.1 From 7d9b39946601e1c7cd393d09db40892bca5cf477 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 18:28:17 +0700 Subject: fix ep type bulk typo --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 29e1ca111..346cf8164 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -488,7 +488,6 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *req (void)rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && - request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) { uint8_t const dev_addr = (uint8_t)request->wValue; @@ -605,7 +604,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { // Set type switch (desc_ep->bmAttributes.xfer) { case TUSB_XFER_BULK: - ep_reg |= USB_EP_CONTROL; // FIXME should it be bulk? + ep_reg |= USB_EP_BULK; break; case TUSB_XFER_INTERRUPT: ep_reg |= USB_EP_INTERRUPT; -- cgit v1.3.1 From 332f75cd44b58d340d36f30dbeb64742767a521c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 20:53:42 +0700 Subject: simplify read/write 16-bit packet --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 139 +++++++++++++------------- src/portable/st/stm32_fsdev/fsdev_ch32.h | 23 ----- src/portable/st/stm32_fsdev/fsdev_type.h | 38 ++++--- 3 files changed, 87 insertions(+), 113 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 346cf8164..cff328418 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -171,8 +171,8 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir); static uint16_t ep_buf_ptr; ///< Points to first free memory location static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf); static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type); -static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes); -static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes); +static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes); +static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes); static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes); static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes); @@ -828,10 +828,10 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { #ifdef FSDEV_BUS_32BIT static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) { const uint8_t *src8 = src; - volatile uint32_t *dst32 = (volatile uint32_t *)(USB_PMAADDR + dst); + volatile uint32_t *pma32 = (volatile uint32_t *)(USB_PMAADDR + dst); for (uint32_t n = wNBytes / 4; n > 0; --n) { - *dst32++ = tu_unaligned_read32(src8); + *pma32++ = tu_unaligned_read32(src8); src8 += 4; } @@ -849,11 +849,41 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui } } - *dst32 = wrVal; + *pma32 = wrVal; } return true; } + +static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { + uint8_t *dst8 = dst; + volatile uint32_t *src32 = (volatile uint32_t *)(USB_PMAADDR + src); + + for (uint32_t n = wNBytes / 4; n > 0; --n) { + tu_unaligned_write32(dst8, *src32++); + dst8 += 4; + } + + uint16_t odd = wNBytes & 0x03; + if (odd) { + uint32_t rdVal = *src32; + + *dst8 = tu_u32_byte0(rdVal); + odd--; + + if (odd) { + *++dst8 = tu_u32_byte1(rdVal); + odd--; + + if (odd) { + *++dst8 = tu_u32_byte2(rdVal); + } + } + } + + return true; +} + #else // Packet buffer access can only be 8- or 16-bit. /** @@ -862,26 +892,52 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui * @param dst, byte address in PMA; must be 16-bit aligned * @param src pointer to user memory area. * @param wPMABufAddr address into PMA. - * @param wNBytes no. of bytes to be copied. + * @param nbytes no. of bytes to be copied. * @retval None */ -static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) { - uint32_t n = (uint32_t)wNBytes >> 1U; +static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) { + uint32_t n16 = (uint32_t)nbytes >> 1U; const uint8_t *src8 = src; - volatile uint16_t *pdw16 = &pma[FSDEV_PMA_STRIDE * (dst >> 1)]; + fsdev_pma16_t* pma16 = (fsdev_pma16_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE * dst); - while (n--) { - *pdw16 = tu_unaligned_read16(src8); + while (n16--) { + pma16->u16 = tu_unaligned_read16(src8); src8 += 2; - pdw16 += FSDEV_PMA_STRIDE; + pma16++; + } + + if (nbytes & 0x01) { + pma16->u16 = (uint16_t) *src8; + } + + return true; +} + +/** + * @brief Copy a buffer from packet memory area (PMA) to user memory area. + * Uses unaligned for system memory and 16-bit access of packet memory + * @param nbytes no. of bytes to be copied. + * @retval None + */ +static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) { + uint32_t n16 = (uint32_t)nbytes >> 1U; + fsdev_pma16_t* pma16 = (fsdev_pma16_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE * src); + uint8_t *dst8 = (uint8_t *)dst; + + while (n16--) { + uint16_t temp16 = pma16->u16; + tu_unaligned_write16(dst8, temp16); + dst8 += 2; + pma16++; } - if (wNBytes & 0x01) { - *pdw16 = (uint16_t) *src8; + if (nbytes & 0x01) { + *dst8++ = tu_u16_low(pma16->u16); } return true; } + #endif /** @@ -959,61 +1015,6 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNB return true; } -#ifdef FSDEV_BUS_32BIT -static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { - uint8_t *dst8 = dst; - volatile uint32_t *src32 = (volatile uint32_t *)(USB_PMAADDR + src); - - for (uint32_t n = wNBytes / 4; n > 0; --n) { - tu_unaligned_write32(dst8, *src32++); - dst8 += 4; - } - - uint16_t odd = wNBytes & 0x03; - if (odd) { - uint32_t rdVal = *src32; - - *dst8 = tu_u32_byte0(rdVal); - odd--; - - if (odd) { - *++dst8 = tu_u32_byte1(rdVal); - odd--; - - if (odd) { - *++dst8 = tu_u32_byte2(rdVal); - } - } - } - - return true; -} -#else -/** - * @brief Copy a buffer from packet memory area (PMA) to user memory area. - * Uses unaligned for system memory and 16-bit access of packet memory - * @param wNBytes no. of bytes to be copied. - * @retval None - */ -static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { - uint32_t n = (uint32_t)wNBytes >> 1U; - volatile const uint16_t *pdw16 = &pma[FSDEV_PMA_STRIDE * (src >> 1)]; - uint8_t *dst8 = (uint8_t *)dst; - - while (n--) { - tu_unaligned_write16(dst8, *pdw16); - dst8 += 2; - pdw16 += FSDEV_PMA_STRIDE; - } - - if (wNBytes & 0x01) { - *dst8++ = tu_u16_low(*pdw16); - } - - return true; -} -#endif - /** * @brief Copy a buffer from user packet memory area (PMA) to FIFO. * Uses byte-access of system memory and 16-bit access of packet memory diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h index 81ef08b8a..8c0961bb9 100644 --- a/src/portable/st/stm32_fsdev/fsdev_ch32.h +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -54,29 +54,6 @@ #endif #define FSDEV_PMA_SIZE (512u) - -#if 1 -// volatile 32-bit aligned -#define _vaa32 volatile TU_ATTR_ALIGNED(4) - -typedef struct { - _vaa32 uint16_t EP0R; // 00: USB Endpoint 0 register - _vaa32 uint16_t EP1R; // 04: USB Endpoint 1 register - _vaa32 uint16_t EP2R; // 08: USB Endpoint 2 register - _vaa32 uint16_t EP3R; // 0C: USB Endpoint 3 register - _vaa32 uint16_t EP4R; // 10: USB Endpoint 4 register - _vaa32 uint16_t EP5R; // 14: USB Endpoint 5 register - _vaa32 uint16_t EP6R; // 18: USB Endpoint 6 register - _vaa32 uint16_t EP7R; // 1C: USB Endpoint 7 register - _vaa32 uint16_t RESERVED7[16]; // Reserved - _vaa32 uint16_t CNTR; // 40: Control register - _vaa32 uint16_t ISTR; // 44: Interrupt status register - _vaa32 uint16_t FNR; // 48: Frame number register - _vaa32 uint16_t DADDR; // 4C: Device address register - _vaa32 uint16_t BTABLE; // 50: Buffer Table address register -} USB_TypeDef; -#endif - #define FSDEV_REG_BASE 0x40005C00UL #define USB_BASE (APB1PERIPH_BASE + 0x00005C00UL) /*!< USB_IP Peripheral Registers base address */ diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index 116017f63..e4a0f3f28 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -75,21 +75,19 @@ enum { // Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either // 16-bit or 32-bit depending on FSDEV_BUS_32BIT. -typedef struct { - union { - // 0: TX (IN), 1: RX (OUT) - - // strictly 16-bit access (could be 32-bit aligned) - struct { - volatile pma_aligned uint16_t addr; - volatile pma_aligned uint16_t count; - } ep16[FSDEV_EP_COUNT][2]; - - // strictly 32-bit access - struct { - volatile uint32_t count_addr; - } ep32[FSDEV_EP_COUNT][2]; - }; +typedef union { + // 0: TX (IN), 1: RX (OUT) + + // strictly 16-bit access (could be 32-bit aligned) + struct { + volatile pma_aligned uint16_t addr; + volatile pma_aligned uint16_t count; + } ep16[FSDEV_EP_COUNT][2]; + + // strictly 32-bit access + struct { + volatile uint32_t count_addr; + } ep32[FSDEV_EP_COUNT][2]; } fsdev_btable_t; TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT*8*FSDEV_PMA_STRIDE, "size is not correct"); @@ -97,6 +95,10 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE #define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) +typedef struct { + volatile pma_aligned uint16_t u16; +} fsdev_pma16_t; + //--------------------------------------------------------------------+ // Registers Typedef //--------------------------------------------------------------------+ @@ -105,16 +107,10 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE #define _va32 volatile TU_ATTR_ALIGNED(4) // The fsdev_bus_t type can be used for both register and PMA access necessities -// For type-safety create a new macro for the volatile address of PMAADDR -// The compiler should warn us if we cast it to a non-volatile type? #ifdef FSDEV_BUS_32BIT typedef uint32_t fsdev_bus_t; -static volatile uint32_t * const pma32 = (volatile uint32_t*)USB_PMAADDR; - #else typedef uint16_t fsdev_bus_t; -// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) -static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; #endif typedef struct { -- cgit v1.3.1 From 5fa03dd906574e775ec025b12ee6c1bc490d87b9 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 1 Aug 2024 13:00:38 +0700 Subject: add stm32g0 (fsdev 2k) to hil pool remove esp32s3 since cp210x cause usb bus issue in the long run --- .github/workflows/build.yml | 4 +--- .github/workflows/hil_test.yml | 14 ++++++----- test/hil/hil_test.py | 10 ++++++-- test/hil/rpi.json | 53 ++++++++++++++++++++++++------------------ 4 files changed, 48 insertions(+), 33 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 712c7dd43..fda7f0294 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -120,10 +120,8 @@ jobs: fail-fast: false matrix: board: - # ESP32-S2 - 'espressif_kaluga_1' - # ESP32-S3 skip since devkitm is also compiled in hil-test workflow - #- 'espressif_s3_devkitm' + - 'espressif_s3_devkitm' with: build-system: 'cmake' toolchain: 'esp-idf' diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index 51227d408..a95bd9bb8 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -66,9 +66,11 @@ jobs: cmake-build/cmake-build-*/*/*/*.bin # --------------------------------------- - # Build Espressif + # Build Espressif (skipped since CP210x cause USB bus issue) + # cp210x ttyUSB0: usb_serial_generic_write_bulk_callback - nonzero urb status: -71 # --------------------------------------- build-esp: + if: false runs-on: ubuntu-latest outputs: BOARDS_LIST: ${{ steps.parse_hil_json.outputs.BOARDS_LIST }} @@ -121,10 +123,10 @@ jobs: if: github.repository_owner == 'hathach' needs: - build - - build-esp + #- build-esp runs-on: [self-hosted, ARM64, rpi, hardware-in-the-loop] env: - BOARDS_LIST: "${{ needs.build.outputs.BOARDS_LIST }} ${{ needs.build-esp.outputs.BOARDS_LIST }}" + BOARDS_LIST: "${{ needs.build-esp.outputs.BOARDS_LIST }} ${{ needs.build.outputs.BOARDS_LIST }}" steps: - name: Clean workspace run: | @@ -135,9 +137,9 @@ jobs: # USB bus on rpi is not stable, reset it before testing # - name: Reset USB bus # run: | -# # reset VIA Labs 2.0 hub -# sudo usbreset 001/002 -# lsusb -t +# echo "1-2" | sudo tee /sys/bus/usb/drivers/usb/unbind +# sleep 5 +# echo "1-2" | sudo tee /sys/bus/usb/drivers/usb/bind - name: Checkout TinyUSB uses: actions/checkout@v4 diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index e2a2f01a0..bda66a2b5 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -138,10 +138,15 @@ def flash_jlink(board, firmware): def flash_stlink(board, firmware): - #ret = run_cmd(f'st-flash --serial {board["flasher_sn"]} write {firmware}.bin 0x08000000') ret = run_cmd(f'STM32_Programmer_CLI --connect port=swd sn={board["flasher_sn"]} --write {firmware}.elf --go') return ret + +def flash_stflash(board, firmware): + ret = run_cmd(f'st-flash --serial {board["flasher_sn"]} write {firmware}.bin 0x8000000') + return ret + + def flash_openocd(board, firmware): ret = run_cmd(f'openocd -c "adapter serial {board["flasher_sn"]}" {board["flasher_args"]} -c "program {firmware}.elf reset exit"') return ret @@ -378,7 +383,8 @@ def main(): if not os.path.exists(fw_dir): fw_dir = f'examples/cmake-build-{name}/device/{test}' fw_name = f'{fw_dir}/{test}' - print(f' {test} ...', end='') + print(f' {test} ... ', end='') + sys.stdout.flush() if not os.path.exists(fw_dir): print('Skip') diff --git a/test/hil/rpi.json b/test/hil/rpi.json index dae3094b5..4d9b0f216 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -1,12 +1,5 @@ { "boards": [ - { - "name": "raspberry_pi_pico", - "uid": "E6614C311B764A37", - "flasher": "openocd", - "flasher_sn": "E6614103E72C1D2F", - "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"" - }, { "name": "feather_nrf52840_express", "uid": "1F0479CD0F764471", @@ -21,16 +14,6 @@ "flasher_sn": "E6614C311B597D32", "flasher_args": "-f interface/cmsis-dap.cfg -f target/atsame5x.cfg -c \"adapter speed 5000\"" }, - { - "name": "espressif_s3_devkitm", - "uid": "84F703C084E4", - "tests": [ - "cdc_msc_freertos", "hid_composite_freertos" - ], - "flasher": "esptool", - "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", - "flasher_args": "-b 921600" - }, { "name": "metro_m7_1011", "uid": "9CE8715DD71137363E00005002004200", @@ -38,6 +21,13 @@ "flasher_sn": "000611000000", "flasher_args": "-device MIMXRT1011xxx5A" }, + { + "name": "lpcxpresso11u37", + "uid": "17121919", + "flasher": "jlink", + "flasher_sn": "000724441579", + "flasher_args": "-device LPC11U37/401" + }, { "name": "ra4m1_ek", "uid": "152E163038303131393346E46F26574B", @@ -48,11 +38,30 @@ "flasher_args": "-device R7FA4M1AB" }, { - "name": "lpcxpresso11u37", - "uid": "17121919", - "flasher": "jlink", - "flasher_sn": "000724441579", - "flasher_args": "-device LPC11U37/401" + "name": "raspberry_pi_pico", + "uid": "E6614C311B764A37", + "flasher": "openocd", + "flasher_sn": "E6614103E72C1D2F", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"" + }, + { + "name": "stm32g0b1nucleo", + "uid": "4D0038000450434E37343120", + "flasher": "openocd", + "flasher_sn": "066FFF495087534867063844", + "flasher_args": "-f interface/stlink.cfg -f target/stm32g0x.cfg" + } + ], + "boards-skip": [ + { + "name": "espressif_s3_devkitm", + "uid": "84F703C084E4", + "tests": [ + "cdc_msc_freertos", "hid_composite_freertos" + ], + "flasher": "esptool", + "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", + "flasher_args": "-b 921600" } ] } -- cgit v1.3.1 From 4e114b7bfa1c694e587c81993560424627ded26e Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 1 Aug 2024 14:01:35 +0700 Subject: update hil ci --- .github/workflows/hil_test.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index a95bd9bb8..4939cdcff 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -149,13 +149,6 @@ jobs: - name: Download Artifacts uses: actions/download-artifact@v4 with: - name: hil_rpi - path: cmake-build - - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - name: hil_rpi_esp path: cmake-build - name: Test on actual hardware -- cgit v1.3.1 From 8407252fa351e80a0abb3cfe4952213f96b486cd Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 1 Aug 2024 14:13:03 +0700 Subject: fix hil ci --- .github/workflows/hil_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index 4939cdcff..a4573faf7 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -150,6 +150,7 @@ jobs: uses: actions/download-artifact@v4 with: path: cmake-build + merge-multiple: true - name: Test on actual hardware run: | -- cgit v1.3.1 From 46fd82299040ff8c572f2b991f5226bf18405ffe Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 1 Aug 2024 14:24:23 +0700 Subject: increase freerto min task stack for some stm32 --- hw/bsp/family_support.cmake | 19 +++++++++++++++++++ hw/bsp/stm32f0/FreeRTOSConfig/FreeRTOSConfig.h | 2 +- hw/bsp/stm32g0/FreeRTOSConfig/FreeRTOSConfig.h | 2 +- hw/bsp/stm32g0/family.cmake | 5 +++-- hw/bsp/stm32h5/FreeRTOSConfig/FreeRTOSConfig.h | 2 +- src/device/usbd.c | 2 +- 6 files changed, 26 insertions(+), 6 deletions(-) diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 6a1e96624..9a7eaeb92 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -428,6 +428,19 @@ function(family_flash_stlink TARGET) endfunction() +# Add flash st-flash target +function(family_flash_stflash TARGET) + if (NOT DEFINED ST_FLASH) + set(ST_FLASH st-flash) + endif () + + add_custom_target(${TARGET}-stflash + DEPENDS ${TARGET} + COMMAND ${ST_FLASH} write $/${TARGET}.bin 0x8000000 + ) +endfunction() + + # Add flash openocd target function(family_flash_openocd TARGET) if (NOT DEFINED OPENOCD) @@ -449,6 +462,7 @@ function(family_flash_openocd TARGET) ) endfunction() + # Add flash openocd-wch target # compiled from https://github.com/hathach/riscv-openocd-wch or https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz function(family_flash_openocd_wch TARGET) @@ -459,6 +473,7 @@ function(family_flash_openocd_wch TARGET) family_flash_openocd(${TARGET}) endfunction() + # Add flash with https://github.com/ch32-rs/wlink function(family_flash_wlink_rs TARGET) if (NOT DEFINED WLINK_RS) @@ -471,6 +486,7 @@ function(family_flash_wlink_rs TARGET) ) endfunction() + # Add flash pycod target function(family_flash_pyocd TARGET) if (NOT DEFINED PYOC) @@ -483,6 +499,7 @@ function(family_flash_pyocd TARGET) ) endfunction() + # Flash with UF2 function(family_flash_uf2 TARGET FAMILY_ID) add_custom_target(${TARGET}-uf2 @@ -491,6 +508,7 @@ function(family_flash_uf2 TARGET FAMILY_ID) ) endfunction() + # Add flash teensy_cli target function(family_flash_teensy TARGET) if (NOT DEFINED TEENSY_CLI) @@ -503,6 +521,7 @@ function(family_flash_teensy TARGET) ) endfunction() + # Add flash using NXP's LinkServer (redserver) # https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/linkserver-for-microcontrollers:LINKERSERVER function(family_flash_nxplink TARGET) diff --git a/hw/bsp/stm32f0/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32f0/FreeRTOSConfig/FreeRTOSConfig.h index 37e7e0943..999dbfe9e 100644 --- a/hw/bsp/stm32f0/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/stm32f0/FreeRTOSConfig/FreeRTOSConfig.h @@ -58,7 +58,7 @@ #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) -#define configMINIMAL_STACK_SIZE ( 128 ) +#define configMINIMAL_STACK_SIZE ( 200 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 diff --git a/hw/bsp/stm32g0/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32g0/FreeRTOSConfig/FreeRTOSConfig.h index 82cb0cdb3..76133ea2d 100644 --- a/hw/bsp/stm32g0/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/stm32g0/FreeRTOSConfig/FreeRTOSConfig.h @@ -58,7 +58,7 @@ #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) -#define configMINIMAL_STACK_SIZE ( 128 ) +#define configMINIMAL_STACK_SIZE ( 200 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 diff --git a/hw/bsp/stm32g0/family.cmake b/hw/bsp/stm32g0/family.cmake index b6838c619..0dafa9c0a 100644 --- a/hw/bsp/stm32g0/family.cmake +++ b/hw/bsp/stm32g0/family.cmake @@ -15,7 +15,7 @@ set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32G0 CACHE INTERNAL "") - +set(OPENOCD_OPTION "-f interface/stlink.cfg -f target/stm32g0x.cfg") #------------------------------------ # BOARD_TARGET @@ -112,6 +112,7 @@ function(family_configure_example TARGET RTOS) target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) # Flashing - family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) + family_flash_stlink(${TARGET}) + #family_flash_openocd(${TARGET}) endfunction() diff --git a/hw/bsp/stm32h5/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32h5/FreeRTOSConfig/FreeRTOSConfig.h index cf6e23c1b..6a9c90a4a 100644 --- a/hw/bsp/stm32h5/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/stm32h5/FreeRTOSConfig/FreeRTOSConfig.h @@ -58,7 +58,7 @@ #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) -#define configMINIMAL_STACK_SIZE ( 128 ) +#define configMINIMAL_STACK_SIZE ( 200 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 diff --git a/src/device/usbd.c b/src/device/usbd.c index d9b20d26d..6d27a3735 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1201,7 +1201,7 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) break; case DCD_EVENT_SETUP_RECEIVED: - // TU_ASSERT(event->setup_received.bRequest != 0,); + // TU_ASSERT(event->setup_received.bRequest != 0,); // for catching issue with ch32v203 and windows with -O0/-Og _usbd_queued_setup++; send = true; break; -- cgit v1.3.1 From f5d8796a6c59714d3096cf78cd7b4e8e114993a1 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 1 Aug 2024 15:24:55 +0700 Subject: add f072 (fsdev 1k) to hil test --- .github/workflows/cifuzz.yml | 2 +- test/hil/rpi.json | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 622d261a0..d7f1fc066 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -26,7 +26,7 @@ jobs: with: oss-fuzz-project-name: 'tinyusb' language: c++ - fuzz-seconds: 600 + fuzz-seconds: 400 - name: Upload Crash uses: actions/upload-artifact@v4 diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 4d9b0f216..9520f30e2 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -44,6 +44,13 @@ "flasher_sn": "E6614103E72C1D2F", "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"" }, + { + "name": "stm32f072disco", + "uid": "3A001A001357364230353532", + "flasher": "jlink", + "flasher_sn": "779541626", + "flasher_args": "-device stm32f072rb" + }, { "name": "stm32g0b1nucleo", "uid": "4D0038000450434E37343120", -- cgit v1.3.1 From 3f4f6c0ec7f5c95ca8a1965a078c0f92d0d4e8ad Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 1 Aug 2024 15:40:47 +0700 Subject: increase hil timeout, reduce fuzzing from 600 to 400 seconds --- test/hil/hil_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index bda66a2b5..bdc48591e 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -43,7 +43,7 @@ if platform.machine() == 'aarch64': pass -ENUM_TIMEOUT = 10 +ENUM_TIMEOUT = 30 # get usb serial by id -- cgit v1.3.1 From af8609e96e269a423449cfb679977c150494c3a4 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 1 Aug 2024 18:36:28 +0700 Subject: fsdev improve ep bit manipulation --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 46 +++++++++++++-------------- src/portable/st/stm32_fsdev/fsdev_type.h | 17 +++++----- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index cff328418..d1c40deb6 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -353,11 +353,11 @@ static void handle_ctr_rx(uint32_t ep_id) { dcd_event_setup_received(0, (uint8_t*) setup_packet, true); // Reset EP to NAK (in case it had been stalling) - ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_NAK); - ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); + ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); + ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); - ep_reg = ep_add_dtog(ep_reg, TUSB_DIR_IN, 1); - ep_reg = ep_add_dtog(ep_reg, TUSB_DIR_OUT, 1); + ep_add_dtog(&ep_reg, TUSB_DIR_IN, 1); + ep_add_dtog(&ep_reg, TUSB_DIR_OUT, 1); } else { ep_reg &= USB_EPREG_MASK; // reversed all toggle } @@ -395,14 +395,14 @@ static void handle_ctr_rx(uint32_t ep_id) { // prepared for status packet btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); } - ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); + ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); } else { // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always if (!is_iso) { uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); } - ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); + ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); } } @@ -579,8 +579,8 @@ void edpt0_open(uint8_t rhport) { uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; ep_reg |= USB_EP_CONTROL; - ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_NAK); - ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); + ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); + ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); // no need to explicitly set DTOG bits since we aren't masked DTOG bit // prepare for setup packet @@ -623,8 +623,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { xfer->max_packet_size = packet_size; xfer->ep_idx = ep_idx; - ep_reg = ep_add_status(ep_reg, dir, EP_STAT_NAK); - ep_reg = ep_add_dtog(ep_reg, dir, 0); + ep_add_status(&ep_reg, dir, EP_STAT_NAK); + ep_add_dtog(&ep_reg, dir, 0); // reserve other direction toggle bits if (dir == TUSB_DIR_IN) { @@ -694,10 +694,10 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX; - ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); - ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); - ep_reg = ep_add_dtog(ep_reg, dir, 0); - ep_reg = ep_add_dtog(ep_reg, 1-dir, 1); + ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); + ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); + ep_add_dtog(&ep_reg, dir, 0); + ep_add_dtog(&ep_reg, 1-dir, 1); ep_write(ep_idx, ep_reg); @@ -707,7 +707,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) // Currently, single-buffered, and only 64 bytes at a time (max) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); - uint16_t ep_reg = ep_read(ep_ix) | EP_CTR_TXRX; + uint32_t ep_reg = ep_read(ep_ix) | EP_CTR_TXRX; bool const is_iso = ep_is_iso(ep_reg); uint8_t buf_id; @@ -727,8 +727,8 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { xfer->queued_len = (uint16_t)(xfer->queued_len + len); ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); - ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_VALID); - ep_reg = ep_clear_ctr(ep_reg, TUSB_DIR_IN); + ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_VALID); + ep_clear_ctr(&ep_reg, TUSB_DIR_IN); dcd_int_disable(0); ep_write(ep_ix, ep_reg); @@ -748,9 +748,9 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { dcd_transmit_packet(xfer, ep_idx); } else { uint32_t cnt = (uint32_t) tu_min16(xfer->total_len, xfer->max_packet_size); - uint16_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX; - ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); // keep CTR TX, clear CTR RX - ep_reg = ep_add_status(ep_reg, dir, EP_STAT_VALID); + uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX; // keep CTR TX, clear CTR RX + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); + ep_add_status(&ep_reg, dir, EP_STAT_VALID); if (ep_is_iso(ep_reg)) { btable_set_rx_bufsize(ep_idx, 0, cnt); @@ -801,7 +801,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { uint32_t ep_reg = ep_read(ep_idx); ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); - ep_reg = ep_add_status(ep_reg, dir, EP_STAT_STALL); + ep_add_status(&ep_reg, dir, EP_STAT_STALL); ep_write(ep_idx, ep_reg); } @@ -818,9 +818,9 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); if (!ep_is_iso(ep_reg)) { - ep_reg = ep_add_status(ep_reg, dir, EP_STAT_NAK); + ep_add_status(&ep_reg, dir, EP_STAT_NAK); } - ep_reg = ep_add_dtog(ep_reg, dir, 0); // Reset to DATA0 + ep_add_dtog(&ep_reg, dir, 0); // Reset to DATA0 ep_write(ep_idx, ep_reg); } diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index e4a0f3f28..a44d8b35b 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -75,10 +75,9 @@ enum { // Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either // 16-bit or 32-bit depending on FSDEV_BUS_32BIT. +// 0: TX (IN), 1: RX (OUT) typedef union { - // 0: TX (IN), 1: RX (OUT) - - // strictly 16-bit access (could be 32-bit aligned) + // data is strictly 16-bit access (address could be 32-bit aligned) struct { volatile pma_aligned uint16_t addr; volatile pma_aligned uint16_t count; @@ -181,16 +180,16 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { return FSDEV_REG->ep[ep_id].reg; } -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) { - return reg ^ (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +TU_ATTR_ALWAYS_INLINE static inline void ep_add_status(uint32_t* reg, tusb_dir_t dir, ep_stat_t state) { + *reg ^= (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_t dir, uint8_t state) { - return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +TU_ATTR_ALWAYS_INLINE static inline void ep_add_dtog(uint32_t* reg, tusb_dir_t dir, uint8_t state) { + *reg ^= (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_clear_ctr(uint32_t reg, tusb_dir_t dir) { - return reg & ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +TU_ATTR_ALWAYS_INLINE static inline void ep_clear_ctr(uint32_t* reg, tusb_dir_t dir) { + *reg &= ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { -- cgit v1.3.1 From e180d915c64c98ce7349cf4696f23abd55a91e19 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 1 Aug 2024 23:08:12 +0700 Subject: read/write packet enhancement, merge 16-bit and 32-bit together --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 139 +++++++++----------------- src/portable/st/stm32_fsdev/fsdev_type.h | 24 +++-- 2 files changed, 60 insertions(+), 103 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index d1c40deb6..2aa776dbb 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -825,121 +825,76 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { ep_write(ep_idx, ep_reg); } -#ifdef FSDEV_BUS_32BIT -static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) { - const uint8_t *src8 = src; - volatile uint32_t *pma32 = (volatile uint32_t *)(USB_PMAADDR + dst); - - for (uint32_t n = wNBytes / 4; n > 0; --n) { - *pma32++ = tu_unaligned_read32(src8); - src8 += 4; - } - - uint16_t odd = wNBytes & 0x03; - if (odd) { - uint32_t wrVal = *src8; - odd--; - - if (odd) { - wrVal |= *++src8 << 8; - odd--; - - if (odd) { - wrVal |= *++src8 << 16; - } - } - - *pma32 = wrVal; - } +// Write to packet memory area (PMA) from user memory +// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT +// - Uses unaligned for RAM (since M0 cannot access unaligned address) +static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) { + enum { BUS_SIZE = sizeof(fsdev_bus_t) }; + uint32_t n_write = nbytes / BUS_SIZE; - return true; -} + fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(dst); + const uint8_t *src8 = src; -static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { - uint8_t *dst8 = dst; - volatile uint32_t *src32 = (volatile uint32_t *)(USB_PMAADDR + src); + while (n_write--) { + #ifdef FSDEV_BUS_32BIT + pma_buf->value = tu_unaligned_read32(src8); + #else + pma_buf->value = tu_unaligned_read16(src8); + #endif - for (uint32_t n = wNBytes / 4; n > 0; --n) { - tu_unaligned_write32(dst8, *src32++); - dst8 += 4; + src8 += BUS_SIZE; + pma_buf++; } - uint16_t odd = wNBytes & 0x03; + // odd bytes e.g 1 for 16-bit or 1-3 for 32-bit + uint16_t odd = nbytes & (BUS_SIZE - 1); if (odd) { - uint32_t rdVal = *src32; - - *dst8 = tu_u32_byte0(rdVal); - odd--; - - if (odd) { - *++dst8 = tu_u32_byte1(rdVal); - odd--; - - if (odd) { - *++dst8 = tu_u32_byte2(rdVal); - } + fsdev_bus_t temp = 0; + for(uint16_t i = 0; i < odd; i++) { + temp |= *src8++ << (i * 8); } + pma_buf->value = temp; } return true; } -#else -// Packet buffer access can only be 8- or 16-bit. -/** - * @brief Copy a buffer from user memory area to packet memory area (PMA). - * This uses un-aligned for user memory and 16-bit access for packet memory. - * @param dst, byte address in PMA; must be 16-bit aligned - * @param src pointer to user memory area. - * @param wPMABufAddr address into PMA. - * @param nbytes no. of bytes to be copied. - * @retval None - */ -static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) { - uint32_t n16 = (uint32_t)nbytes >> 1U; - const uint8_t *src8 = src; - fsdev_pma16_t* pma16 = (fsdev_pma16_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE * dst); - - while (n16--) { - pma16->u16 = tu_unaligned_read16(src8); - src8 += 2; - pma16++; - } +// Read from packet memory area (PMA) to user memory. +// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT +// - Uses unaligned for RAM (since M0 cannot access unaligned address) +static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) { + enum { BUS_SIZE = sizeof(fsdev_bus_t) }; + uint32_t n_write = nbytes / BUS_SIZE; - if (nbytes & 0x01) { - pma16->u16 = (uint16_t) *src8; - } + fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(src); + uint8_t *dst8 = (uint8_t *)dst; - return true; -} + while (n_write--) { + fsdev_bus_t temp = pma_buf->value; -/** - * @brief Copy a buffer from packet memory area (PMA) to user memory area. - * Uses unaligned for system memory and 16-bit access of packet memory - * @param nbytes no. of bytes to be copied. - * @retval None - */ -static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) { - uint32_t n16 = (uint32_t)nbytes >> 1U; - fsdev_pma16_t* pma16 = (fsdev_pma16_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE * src); - uint8_t *dst8 = (uint8_t *)dst; + #ifdef FSDEV_BUS_32BIT + tu_unaligned_write32(dst8, temp); + #else + tu_unaligned_write16(dst8, temp); + #endif - while (n16--) { - uint16_t temp16 = pma16->u16; - tu_unaligned_write16(dst8, temp16); - dst8 += 2; - pma16++; + dst8 += BUS_SIZE; + pma_buf++; } - if (nbytes & 0x01) { - *dst8++ = tu_u16_low(pma16->u16); + // odd bytes e.g 1 for 16-bit or 1-3 for 32-bit + uint16_t odd = nbytes & (BUS_SIZE - 1); + if (odd) { + fsdev_bus_t temp = pma_buf->value; + while (odd--) { + *dst8++ = (uint8_t) (temp & 0xfful); + temp >>= 8; + } } return true; } -#endif - /** * @brief Copy from FIFO to packet memory area (PMA). * Uses byte-access of system memory and 16-bit access of packet memory diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index a44d8b35b..cac3b4386 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -1,9 +1,8 @@ /* * The MIT License (MIT) * - * Copyright(c) 2016 STMicroelectronics * Copyright(c) N Conrad - * Copyright (c) 2024, hathach (tinyusb.org) + * Copyright(c) 2024, hathach (tinyusb.org) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,6 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * + * This file is part of the TinyUSB stack. */ #ifndef TUSB_FSDEV_TYPE_H @@ -62,6 +62,13 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b #define pma_aligned #endif +// The fsdev_bus_t type can be used for both register and PMA access necessities +#ifdef FSDEV_BUS_32BIT + typedef uint32_t fsdev_bus_t; +#else + typedef uint16_t fsdev_bus_t; +#endif + //--------------------------------------------------------------------+ // BTable Typedef //--------------------------------------------------------------------+ @@ -95,8 +102,10 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE #define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) typedef struct { - volatile pma_aligned uint16_t u16; -} fsdev_pma16_t; + volatile pma_aligned fsdev_bus_t value; +} fsdev_pma_buf_t; + +#define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE*(_addr))) //--------------------------------------------------------------------+ // Registers Typedef @@ -105,13 +114,6 @@ typedef struct { // volatile 32-bit aligned #define _va32 volatile TU_ATTR_ALIGNED(4) -// The fsdev_bus_t type can be used for both register and PMA access necessities -#ifdef FSDEV_BUS_32BIT -typedef uint32_t fsdev_bus_t; -#else -typedef uint16_t fsdev_bus_t; -#endif - typedef struct { struct { _va32 fsdev_bus_t reg; -- cgit v1.3.1 From e9a5af35121820c97a5ed0107e49a67b486c7e4e Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 2 Aug 2024 15:48:39 +0700 Subject: add stm32f103ze_iar --- hw/bsp/family_support.cmake | 8 +- hw/bsp/stm32f1/boards/stm32f103ze_iar/board.cmake | 14 ++++ hw/bsp/stm32f1/boards/stm32f103ze_iar/board.h | 97 +++++++++++++++++++++++ hw/bsp/stm32f1/boards/stm32f103ze_iar/board.mk | 13 +++ hw/bsp/stm32f1/family.c | 35 +++++++- hw/bsp/stm32f1/family.mk | 34 ++++---- 6 files changed, 182 insertions(+), 19 deletions(-) create mode 100644 hw/bsp/stm32f1/boards/stm32f103ze_iar/board.cmake create mode 100644 hw/bsp/stm32f1/boards/stm32f103ze_iar/board.h create mode 100644 hw/bsp/stm32f1/boards/stm32f103ze_iar/board.mk diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 9a7eaeb92..03a24c95b 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -399,6 +399,11 @@ function(family_flash_jlink TARGET) set(JLINK_IF swd) endif () + if (NOT DEFINED JLINK_OPTION) + set(JLINK_OPTION "") + endif () + separate_arguments(OPTION_LIST UNIX_COMMAND ${JLINK_OPTION}) + file(GENERATE OUTPUT $/${TARGET}.jlink CONTENT "halt @@ -410,7 +415,8 @@ exit" add_custom_target(${TARGET}-jlink DEPENDS ${TARGET} - COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile $/${TARGET}.jlink + COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} ${OPTION_LIST} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile $/${TARGET}.jlink + VERBATIM ) endfunction() diff --git a/hw/bsp/stm32f1/boards/stm32f103ze_iar/board.cmake b/hw/bsp/stm32f1/boards/stm32f103ze_iar/board.cmake new file mode 100644 index 000000000..c797d7090 --- /dev/null +++ b/hw/bsp/stm32f1/boards/stm32f103ze_iar/board.cmake @@ -0,0 +1,14 @@ +set(MCU_VARIANT stm32f103xe) +set(JLINK_DEVICE stm32f103ze) + +string(TOUPPER ${MCU_VARIANT} MCU_VARIANT_UPPER) + +set(LD_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/linker/${MCU_VARIANT_UPPER}_FLASH.ld) +set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32F103xE + HSE_VALUE=8000000U + ) +endfunction() diff --git a/hw/bsp/stm32f1/boards/stm32f103ze_iar/board.h b/hw/bsp/stm32f1/boards/stm32f103ze_iar/board.h new file mode 100644 index 000000000..d31102d32 --- /dev/null +++ b/hw/bsp/stm32f1/boards/stm32f103ze_iar/board.h @@ -0,0 +1,97 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOF +#define LED_PIN GPIO_PIN_6 +#define LED_STATE_ON 1 + +// Button +#define BUTTON_PORT GPIOG +#define BUTTON_PIN GPIO_PIN_8 +#define BUTTON_STATE_ACTIVE 0 + +// USB Connect +#define USB_CONNECT_PORT GPIOG +#define USB_CONNECT_PIN GPIO_PIN_11 +#define USB_CONNECT_STATE 0 + +// UART +//#define UART_DEV USART1 +//#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE +//#define UART_GPIO_PORT GPIOA +//#define UART_GPIO_AF GPIO_AF1_USART1 +//#define UART_TX_PIN GPIO_PIN_9 +//#define UART_RX_PIN GPIO_PIN_10 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_stm32f1_clock_init(void) +{ + RCC_ClkInitTypeDef clkinitstruct = {0}; + RCC_OscInitTypeDef oscinitstruct = {0}; + RCC_PeriphCLKInitTypeDef rccperiphclkinit = {0}; + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + oscinitstruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + oscinitstruct.HSEState = RCC_HSE_ON; + oscinitstruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + oscinitstruct.PLL.PLLMUL = RCC_PLL_MUL9; + oscinitstruct.PLL.PLLState = RCC_PLL_ON; + oscinitstruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + HAL_RCC_OscConfig(&oscinitstruct); + + /* USB clock selection */ + rccperiphclkinit.PeriphClockSelection = RCC_PERIPHCLK_USB; + rccperiphclkinit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; + HAL_RCCEx_PeriphCLKConfig(&rccperiphclkinit); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ + clkinitstruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2; + clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2); +} + +static inline void board_vbus_sense_init(void) +{ +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/stm32f1/boards/stm32f103ze_iar/board.mk b/hw/bsp/stm32f1/boards/stm32f103ze_iar/board.mk new file mode 100644 index 000000000..5b17d8036 --- /dev/null +++ b/hw/bsp/stm32f1/boards/stm32f103ze_iar/board.mk @@ -0,0 +1,13 @@ +MCU_VARIANT = stm32f103xe + +CFLAGS += -DSTM32F103xE -DHSE_VALUE=8000000U + +# Linker +LD_FILE_GCC = ${ST_CMSIS}/Source/Templates/gcc/linker/STM32F103XE_FLASH.ld +LD_FILE_IAR = ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf + +# For flash-jlink target +JLINK_DEVICE = stm32f103ze + +# flash target ROM bootloader +flash: flash-jlink diff --git a/hw/bsp/stm32f1/family.c b/hw/bsp/stm32f1/family.c index 70f81e7fc..600fc28c0 100644 --- a/hw/bsp/stm32f1/family.c +++ b/hw/bsp/stm32f1/family.c @@ -57,6 +57,19 @@ void board_init(void) { __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); +#ifdef __HAL_RCC_GPIOE_CLK_ENABLE + __HAL_RCC_GPIOE_CLK_ENABLE(); +#endif + +#ifdef __HAL_RCC_GPIOF_CLK_ENABLE + __HAL_RCC_GPIOF_CLK_ENABLE(); +#endif + +#ifdef __HAL_RCC_GPIOG_CLK_ENABLE + __HAL_RCC_GPIOG_CLK_ENABLE(); +#endif + + #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); @@ -107,10 +120,18 @@ void board_init(void) { HAL_UART_Init(&UartHandle); #endif +#ifdef USB_CONNECT_PIN + GPIO_InitStruct.Pin = USB_CONNECT_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(USB_CONNECT_PORT, &GPIO_InitStruct); +#endif + // USB Pins // Configure USB DM and DP pins. GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); @@ -119,6 +140,18 @@ void board_init(void) { __HAL_RCC_USB_CLK_ENABLE(); } +#ifdef USB_CONNECT_PIN +void dcd_disconnect(uint8_t rhport) { + (void)rhport; + HAL_GPIO_WritePin(USB_CONNECT_PORT, USB_CONNECT_PIN, 1-USB_CONNECT_STATE); +} + +void dcd_connect(uint8_t rhport) { + (void)rhport; + HAL_GPIO_WritePin(USB_CONNECT_PORT, USB_CONNECT_PIN, USB_CONNECT_STATE); +} +#endif + //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ diff --git a/hw/bsp/stm32f1/family.mk b/hw/bsp/stm32f1/family.mk index 03fbf4010..364616304 100644 --- a/hw/bsp/stm32f1/family.mk +++ b/hw/bsp/stm32f1/family.mk @@ -1,10 +1,10 @@ ST_FAMILY = f1 -DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_${ST_FAMILY} hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver -ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) -ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver +ST_CMSIS = hw/mcu/st/cmsis_device_${ST_FAMILY} +ST_HAL_DRIVER = hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver -include $(TOP)/$(BOARD_PATH)/board.mk +include ${TOP}/${BOARD_PATH}/board.mk CPU_CORE ?= cortex-m3 # -------------- @@ -29,23 +29,23 @@ LDFLAGS_GCC += \ # ------------------------ SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ - $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c + ${ST_CMSIS}/Source/Templates/system_stm32${ST_FAMILY}xx.c \ + ${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal.c \ + ${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal_cortex.c \ + ${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal_rcc.c \ + ${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal_rcc_ex.c \ + ${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal_gpio.c \ + ${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal_uart.c INC += \ - $(TOP)/$(BOARD_PATH) \ - $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ - $(TOP)/$(ST_CMSIS)/Include \ - $(TOP)/$(ST_HAL_DRIVER)/Inc + ${TOP}/${BOARD_PATH} \ + ${TOP}/lib/CMSIS_5/CMSIS/Core/Include \ + ${TOP}/${ST_CMSIS}/Include \ + ${TOP}/${ST_HAL_DRIVER}/Inc # Startup -SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_$(MCU_VARIANT).s -SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_$(MCU_VARIANT).s +SRC_S_GCC += ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s +SRC_S_IAR += ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s # flash target ROM bootloader: flash-dfu-util DFU_UTIL_OPTION = -a 0 --dfuse-address 0x08000000 -- cgit v1.3.1 From 91e5a066c5b259c38d663d21e3485b2feecb779d Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 2 Aug 2024 17:12:28 +0700 Subject: more fsdev clean up hil test boards in parallel --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 8 -- src/portable/st/stm32_fsdev/fsdev_ch32.h | 18 +--- src/portable/st/stm32_fsdev/fsdev_stm32.h | 50 +++++------ src/portable/st/stm32_fsdev/fsdev_type.h | 29 ++++--- test/hil/hil_test.py | 120 +++++++++++++------------- 5 files changed, 102 insertions(+), 123 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 2aa776dbb..cbd240ca1 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -114,8 +114,6 @@ #include "device/dcd.h" #if defined(TUP_USBIP_FSDEV_STM32) - // Undefine to reduce the dependence on HAL - #undef USE_HAL_DRIVER #include "fsdev_stm32.h" #elif defined(TUP_USBIP_FSDEV_CH32) #include "fsdev_ch32.h" @@ -125,12 +123,6 @@ #include "fsdev_type.h" -//--------------------------------------------------------------------+ -// Configuration -//--------------------------------------------------------------------+ - - - //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h index 8c0961bb9..518197c47 100644 --- a/src/portable/st/stm32_fsdev/fsdev_ch32.h +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -54,22 +54,8 @@ #endif #define FSDEV_PMA_SIZE (512u) -#define FSDEV_REG_BASE 0x40005C00UL - -#define USB_BASE (APB1PERIPH_BASE + 0x00005C00UL) /*!< USB_IP Peripheral Registers base address */ -#define USB_PMAADDR (APB1PERIPH_BASE + 0x00006000UL) /*!< USB_IP Packet Memory Area base address */ -#define USB ((USB_TypeDef *)USB_BASE) - -/******************************************************************************/ -/* */ -/* USB Device General registers */ -/* */ -/******************************************************************************/ -#define USB_CNTR (USB_BASE + 0x40U) /*!< Control register */ -#define USB_ISTR (USB_BASE + 0x44U) /*!< Interrupt status register */ -#define USB_FNR (USB_BASE + 0x48U) /*!< Frame number register */ -#define USB_DADDR (USB_BASE + 0x4CU) /*!< Device address register */ -#define USB_BTABLE (USB_BASE + 0x50U) /*!< Buffer Table address register */ +#define FSDEV_REG_BASE (APB1PERIPH_BASE + 0x00005C00UL) +#define FSDEV_PMA_BASE (APB1PERIPH_BASE + 0x00006000UL) /**************************** ISTR interrupt events *************************/ #define USB_ISTR_CTR ((uint16_t)0x8000U) /*!< Correct TRansfer (clear-only bit) */ diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index bb2c72fd1..99fe8d55f 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -82,12 +82,9 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32G0 #include "stm32g0xx.h" - #define FSDEV_BUS_32BIT #define FSDEV_PMA_SIZE (2048u) - #undef USB_PMAADDR - #define USB_PMAADDR USB_DRD_PMAADDR - #define USB_TypeDef USB_DRD_TypeDef - #define EP0R CHEP0R + #define USB USB_DRD_FS + #define USB_EP_CTR_RX USB_EP_VTRX #define USB_EP_CTR_TX USB_EP_VTTX #define USB_EP_T_FIELD USB_CHEP_UTYPE @@ -100,7 +97,6 @@ #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 #define USB_EPRX_STAT USB_CH_RX_VALID #define USB_EPKIND_MASK USB_EP_KIND_MASK - #define USB USB_DRD_FS #define USB_CNTR_FRES USB_CNTR_USBRST #define USB_CNTR_RESUME USB_CNTR_L2RES #define USB_ISTR_EP_ID USB_ISTR_IDN @@ -110,17 +106,9 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32H5 #include "stm32h5xx.h" - #define FSDEV_BUS_32BIT - - #if !defined(USB_DRD_BASE) && defined(USB_DRD_FS_BASE) - #define USB_DRD_BASE USB_DRD_FS_BASE - #endif - #define FSDEV_PMA_SIZE (2048u) - #undef USB_PMAADDR - #define USB_PMAADDR USB_DRD_PMAADDR - #define USB_TypeDef USB_DRD_TypeDef - #define EP0R CHEP0R + #define USB USB_DRD_FS + #define USB_EP_CTR_RX USB_EP_VTRX #define USB_EP_CTR_TX USB_EP_VTTX #define USB_EP_T_FIELD USB_CHEP_UTYPE @@ -133,7 +121,6 @@ #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 #define USB_EPRX_STAT USB_CH_RX_VALID #define USB_EPKIND_MASK USB_EP_KIND_MASK - #define USB USB_DRD_FS #define USB_CNTR_FRES USB_CNTR_USBRST #define USB_CNTR_RESUME USB_CNTR_L2RES #define USB_ISTR_EP_ID USB_ISTR_IDN @@ -144,9 +131,8 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32WB #include "stm32wbxx.h" #define FSDEV_PMA_SIZE (1024u) - /* ST provided header has incorrect value */ - #undef USB_PMAADDR - #define USB_PMAADDR USB1_PMAADDR + /* ST provided header has incorrect value of USB_PMAADDR */ + #define FSDEV_PMA_BASE USB1_PMAADDR #elif CFG_TUSB_MCU == OPT_MCU_STM32L4 #include "stm32l4xx.h" @@ -162,13 +148,9 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 #include "stm32u5xx.h" - #define FSDEV_BUS_32BIT - #define FSDEV_PMA_SIZE (2048u) - #undef USB_PMAADDR - #define USB_PMAADDR USB_DRD_PMAADDR - #define USB_TypeDef USB_DRD_TypeDef - #define EP0R CHEP0R + #define USB USB_DRD_FS + #define USB_EP_CTR_RX USB_EP_VTRX #define USB_EP_CTR_TX USB_EP_VTTX #define USB_EP_T_FIELD USB_CHEP_UTYPE @@ -181,7 +163,6 @@ #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 #define USB_EPRX_STAT USB_CH_RX_VALID #define USB_EPKIND_MASK USB_EP_KIND_MASK - #define USB USB_DRD_FS #define USB_CNTR_FRES USB_CNTR_USBRST #define USB_CNTR_RESUME USB_CNTR_L2RES #define USB_ISTR_EP_ID USB_ISTR_IDN @@ -194,6 +175,10 @@ // This includes U0 #endif +//--------------------------------------------------------------------+ +// Register and PMA Base Address +//--------------------------------------------------------------------+ +#ifndef FSDEV_REG_BASE #if defined(USB_BASE) #define FSDEV_REG_BASE USB_BASE #elif defined(USB_DRD_BASE) @@ -203,6 +188,17 @@ #else #error "FSDEV_REG_BASE not defined" #endif +#endif + +#ifndef FSDEV_PMA_BASE +#if defined(USB_PMAADDR) + #define FSDEV_PMA_BASE USB_PMAADDR +#elif defined(USB_DRD_PMAADDR) + #define FSDEV_PMA_BASE USB_DRD_PMAADDR +#else + #error "FSDEV_PMA_BASE not defined" +#endif +#endif // This checks if the device has "LPM" #if defined(USB_ISTR_L1REQ) diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index cac3b4386..bdff2c940 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -49,17 +49,18 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b // For purposes of accessing the packet #if FSDEV_PMA_SIZE == 512 - #define FSDEV_PMA_STRIDE (2u) // 1x16 bit access scheme - #define pma_aligned TU_ATTR_ALIGNED(4) + // 1x16 bit / word access scheme + #define FSDEV_PMA_STRIDE 2 + #define pma_access_scheme TU_ATTR_ALIGNED(4) #elif FSDEV_PMA_SIZE == 1024 - #define FSDEV_PMA_STRIDE (1u) // 2x16 bit access scheme - #define pma_aligned + // 2x16 bit / word access scheme + #define FSDEV_PMA_STRIDE 1 + #define pma_access_scheme #elif FSDEV_PMA_SIZE == 2048 - #ifndef FSDEV_BUS_32BIT - #warning "FSDEV_PMA_SIZE is 2048, but FSDEV_BUS_32BIT is not defined" - #endif - #define FSDEV_PMA_STRIDE (1u) // 32 bit access scheme - #define pma_aligned + // 32 bit access scheme + #define FSDEV_BUS_32BIT + #define FSDEV_PMA_STRIDE 1 + #define pma_access_scheme #endif // The fsdev_bus_t type can be used for both register and PMA access necessities @@ -86,8 +87,8 @@ enum { typedef union { // data is strictly 16-bit access (address could be 32-bit aligned) struct { - volatile pma_aligned uint16_t addr; - volatile pma_aligned uint16_t count; + volatile pma_access_scheme uint16_t addr; + volatile pma_access_scheme uint16_t count; } ep16[FSDEV_EP_COUNT][2]; // strictly 32-bit access @@ -99,13 +100,13 @@ typedef union { TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT*8*FSDEV_PMA_STRIDE, "size is not correct"); TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM"); -#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) +#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (FSDEV_PMA_BASE + FSDEV_PMA_STRIDE*(FSDEV_BTABLE_BASE))) typedef struct { - volatile pma_aligned fsdev_bus_t value; + volatile pma_access_scheme fsdev_bus_t value; } fsdev_pma_buf_t; -#define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE*(_addr))) +#define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t*) (FSDEV_PMA_BASE + FSDEV_PMA_STRIDE*(_addr))) //--------------------------------------------------------------------+ // Registers Typedef diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index bdc48591e..6b8ba0675 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -34,6 +34,7 @@ import subprocess import json import glob import platform +from multiprocessing import Pool # for RPI double reset if platform.machine() == 'aarch64': @@ -130,10 +131,11 @@ def run_cmd(cmd): def flash_jlink(board, firmware): script = ['halt', 'r', f'loadfile {firmware}.elf', 'r', 'go', 'exit'] - with open('flash.jlink', 'w') as f: + f_jlink = f'{board["name"]}_{os.path.basename(firmware)}.jlink' + with open(f_jlink, 'w') as f: f.writelines(f'{s}\n' for s in script) - ret = run_cmd(f'JLinkExe -USB {board["flasher_sn"]} {board["flasher_args"]} -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile flash.jlink') - os.remove('flash.jlink') + ret = run_cmd(f'JLinkExe -USB {board["flasher_sn"]} {board["flasher_args"]} -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile {f_jlink}') + os.remove(f_jlink) return ret @@ -327,6 +329,61 @@ def test_hid_composite_freertos(id): # ------------------------------------------------------------- # Main # ------------------------------------------------------------- +# all possible tests: board_test is added last to disable board's usb +all_tests = [ + 'cdc_dual_ports', + 'cdc_msc', + #'cdc_msc_freertos', + 'dfu', + #'dfu_runtime', + 'hid_boot_interface', + 'board_test' +] + + +def test_board(item): + name = item['name'] + flasher = item['flasher'].lower() + + # default to all tests + if 'tests' in item: + test_list = item['tests'] + ['board_test'] + else: + test_list = list(all_tests) + + # remove skip_tests + if 'tests_skip' in item: + for skip in item['tests_skip']: + if skip in test_list: + test_list.remove(skip) + + for test in test_list: + fw_dir = f'cmake-build/cmake-build-{name}/device/{test}' + if not os.path.exists(fw_dir): + fw_dir = f'examples/cmake-build-{name}/device/{test}' + fw_name = f'{fw_dir}/{test}' + print(f'{name:20} {test:20} ... ', end='') + + if not os.path.exists(fw_dir): + print('Skip') + continue + + # flash firmware. It may fail randomly, retry a few times + for i in range(3): + ret = globals()[f'flash_{flasher}'](item, fw_name) + if ret.returncode == 0: + break + else: + print(f'Flashing failed, retry {i+1}') + time.sleep(1) + + assert ret.returncode == 0, 'Flash failed\n' + ret.stdout.decode() + + # run test + globals()[f'test_{test}'](item['uid']) + print('OK') + + def main(): """ Hardware test on specified boards @@ -345,66 +402,13 @@ def main(): with open(config_file) as f: config = json.load(f) - # all possible tests: board_test is added last to disable board's usb - all_tests = [ - 'cdc_dual_ports', - 'cdc_msc', - 'cdc_msc_freertos', - 'dfu', - 'dfu_runtime', - 'hid_boot_interface', - 'board_test' - ] - if len(boards) == 0: config_boards = config['boards'] else: config_boards = [e for e in config['boards'] if e['name'] in boards] - for item in config_boards: - name = item['name'] - print(f'Testing board:{name}') - flasher = item['flasher'].lower() - - # default to all tests - if 'tests' in item: - test_list = item['tests'] + ['board_test'] - else: - test_list = list(all_tests) - - # remove skip_tests - if 'tests_skip' in item: - for skip in item['tests_skip']: - if skip in test_list: - test_list.remove(skip) - - for test in test_list: - fw_dir = f'cmake-build/cmake-build-{name}/device/{test}' - if not os.path.exists(fw_dir): - fw_dir = f'examples/cmake-build-{name}/device/{test}' - fw_name = f'{fw_dir}/{test}' - print(f' {test} ... ', end='') - sys.stdout.flush() - - if not os.path.exists(fw_dir): - print('Skip') - continue - - # flash firmware. It may fail randomly, retry a few times - for i in range(3): - ret = globals()[f'flash_{flasher}'](item, fw_name) - if ret.returncode == 0: - break - else: - print(f'Flashing failed, retry {i+1}') - time.sleep(1) - - assert ret.returncode == 0, 'Flash failed\n' + ret.stdout.decode() - - # run test - globals()[f'test_{test}'](item['uid']) - - print('OK') + with Pool(processes=os.cpu_count()) as pool: + pool.map(test_board, config_boards) if __name__ == '__main__': -- cgit v1.3.1 From 315dae6a85cbb3df5b30429b28d8c74130f44db6 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 5 Aug 2024 17:43:27 +0700 Subject: finally fixed fsdev setup handling, which cause race condition for ch32v203 --- src/device/usbd.c | 1 - src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 59 ++++++++++++++------------- src/portable/st/stm32_fsdev/fsdev_type.h | 3 -- 3 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 6d27a3735..7089e9cf1 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1201,7 +1201,6 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) break; case DCD_EVENT_SETUP_RECEIVED: - // TU_ASSERT(event->setup_received.bRequest != 0,); // for catching issue with ch32v203 and windows with -O0/-Og _usbd_queued_setup++; send = true; break; diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index cbd240ca1..43636198a 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -147,7 +147,6 @@ typedef struct { static xfer_ctl_t xfer_status[CFG_TUD_ENDPPOINT_MAX][2]; static ep_alloc_t ep_alloc_status[FSDEV_EP_COUNT]; - static uint8_t remoteWakeCountdown; // When wake is requested //--------------------------------------------------------------------+ @@ -171,6 +170,10 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBy static void edpt0_open(uint8_t rhport); +TU_ATTR_ALWAYS_INLINE static inline void edpt0_prepare_setup(void) { + btable_set_rx_bufsize(0, BTABLE_BUF_RX, 8); +} + //--------------------------------------------------------------------+ // Inline helper //--------------------------------------------------------------------+ @@ -340,21 +343,24 @@ static void handle_ctr_rx(uint32_t ep_id) { // Setup packet should always be 8 bytes. If not, ignore it, and try again. if (count == 8) { uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX); - uint32_t setup_packet[2]; + uint8_t setup_packet[8] TU_ATTR_ALIGNED(4); + dcd_read_packet_memory(setup_packet, rx_addr, 8); dcd_event_setup_received(0, (uint8_t*) setup_packet, true); - // Reset EP to NAK (in case it had been stalling) + // Reset EP to NAK and set both toggle to 1 ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); - ep_add_dtog(&ep_reg, TUSB_DIR_IN, 1); ep_add_dtog(&ep_reg, TUSB_DIR_OUT, 1); } else { + // Missed an setup packet !!! + TU_BREAKPOINT(); ep_reg &= USB_EPREG_MASK; // reversed all toggle + edpt0_prepare_setup(); } } else { - ep_reg &= USB_EPRX_STAT | USB_EPREG_MASK; // reversed all toggle except RX Status + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_OUT); // reversed all toggle except RX Status bool const is_iso = ep_is_iso(ep_reg); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT); @@ -374,20 +380,13 @@ static void handle_ctr_rx(uint32_t ep_id) { } else { dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); } - xfer->queued_len = (uint16_t)(xfer->queued_len + rx_count); } if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { - uint8_t const ep_addr = ep_num; // all bytes received or short packet - dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); - - if (ep_num == 0) { - // prepared for status packet - btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); - } ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); + dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); } else { // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always if (!is_iso) { @@ -485,6 +484,8 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *req uint8_t const dev_addr = (uint8_t)request->wValue; FSDEV_REG->DADDR = (USB_DADDR_EF | dev_addr); } + + edpt0_prepare_setup(); } /*** @@ -569,15 +570,13 @@ void edpt0_open(uint8_t rhport) { btable_set_addr(0, BTABLE_BUF_RX, pma_addr0); btable_set_addr(0, BTABLE_BUF_TX, pma_addr1); - uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; + uint32_t ep_reg = ep_read(0) & ~USB_EPREG_MASK; // only get toggle bits ep_reg |= USB_EP_CONTROL; ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); // no need to explicitly set DTOG bits since we aren't masked DTOG bit - // prepare for setup packet - btable_set_rx_bufsize(0, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); - + edpt0_prepare_setup(); // prepare for setup packet ep_write(0, ep_reg); } @@ -590,7 +589,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); TU_ASSERT(ep_idx < FSDEV_EP_COUNT); - uint32_t ep_reg = FSDEV_REG->ep[ep_idx].reg & ~USB_EPREG_MASK; + uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK; ep_reg |= tu_edpt_number(ep_addr) | USB_EP_CTR_RX | USB_EP_CTR_TX; // Set type @@ -684,7 +683,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) xfer->max_packet_size = tu_edpt_packet_size(desc_ep); - uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; + uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK; ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX; ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); @@ -699,7 +698,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) // Currently, single-buffered, and only 64 bytes at a time (max) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); - uint32_t ep_reg = ep_read(ep_ix) | EP_CTR_TXRX; + uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits bool const is_iso = ep_is_iso(ep_reg); uint8_t buf_id; @@ -709,14 +708,17 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { buf_id = BTABLE_BUF_TX; } uint16_t addr_ptr = (uint16_t) btable_get_addr(ep_ix, buf_id); - btable_set_count(ep_ix, buf_id, len); - if (xfer->ff) { - dcd_write_packet_memory_ff(xfer->ff, addr_ptr, len); - } else { - dcd_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len); + if (len) { + if (xfer->ff) { + dcd_write_packet_memory_ff(xfer->ff, addr_ptr, len); + } else { + dcd_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len); + } + xfer->queued_len = (uint16_t) (xfer->queued_len + len); } - xfer->queued_len = (uint16_t)(xfer->queued_len + len); + + btable_set_count(ep_ix, buf_id, len); ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_VALID); @@ -790,8 +792,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); uint8_t const ep_idx = xfer->ep_idx; - uint32_t ep_reg = ep_read(ep_idx); - ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits + uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); ep_add_status(&ep_reg, dir, EP_STAT_STALL); @@ -806,7 +807,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); uint8_t const ep_idx = xfer->ep_idx; - uint32_t ep_reg = ep_read(ep_idx) | EP_CTR_TXRX; + uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); if (!ep_is_iso(ep_reg)) { diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index bdff2c940..8432df4b0 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -156,9 +156,6 @@ TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); #define USB_EP_CTR_TX_Pos 7u #endif - -#define EP_CTR_TXRX (USB_EP_CTR_TX | USB_EP_CTR_RX) - typedef enum { EP_STAT_DISABLED = 0, EP_STAT_STALL = 1, -- cgit v1.3.1 From 30e0ef221aec56c10b9d615bea9d4d9b4ff5e9cc Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 5 Aug 2024 19:23:35 +0700 Subject: fix running hil in parallel --- test/hil/hil_test.py | 73 ++++++++++++++-------------------------------------- 1 file changed, 20 insertions(+), 53 deletions(-) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 6b8ba0675..a221982c0 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -36,14 +36,6 @@ import glob import platform from multiprocessing import Pool -# for RPI double reset -if platform.machine() == 'aarch64': - try: - import gpiozero - except ImportError: - pass - - ENUM_TIMEOUT = 30 @@ -154,6 +146,12 @@ def flash_openocd(board, firmware): return ret +def flash_wlink_rs(board, firmware): + # wlink use index for probe selection and lacking usb serial support + ret = run_cmd(f'wlink flash {firmware}.elf') + return ret + + def flash_esptool(board, firmware): port = get_serial_dev(board["flasher_sn"], None, None, 0) dir = os.path.dirname(f'{firmware}.bin') @@ -167,38 +165,6 @@ def flash_esptool(board, firmware): return ret -def doublereset_with_rpi_gpio(pin): - # Off = 0 = Reset - nrst = gpiozero.LED(pin) - - nrst.off() - time.sleep(0.1) - nrst.on() - time.sleep(0.1) - nrst.off() - time.sleep(0.1) - nrst.on() - - -def flash_bossac(board, firmware): - # double reset to enter bootloader - if platform.machine() == 'aarch64': - doublereset_with_rpi_gpio(board["flasher_reset_pin"]) - - port = get_serial_dev(board["uid"], board["flashser_vendor"], board["flasher_product"], 0) - timeout = ENUM_TIMEOUT - while timeout: - if os.path.exists(port): - break - else: - time.sleep(0.5) - timeout = timeout - 0.5 - assert timeout, 'bossac bootloader is not available' - # sleep a bit more for bootloader to be ready - time.sleep(0.5) - ret = run_cmd(f'bossac --port {port} {board["flasher_args"]} -U -i -R -e -w {firmware}.bin') - return ret - # ------------------------------------------------------------- # Tests # ------------------------------------------------------------- @@ -266,29 +232,30 @@ def test_dfu(id): assert timeout, 'Device not available' + f_dfu0 = f'dfu0_{id}' + f_dfu1 = f'dfu1_{id}' + # Test upload try: - os.remove('dfu0') - os.remove('dfu1') + os.remove(f_dfu0) + os.remove(f_dfu1) except OSError: pass - ret = subprocess.run(f'dfu-util -S {id} -a 0 -U dfu0', - shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + ret = run_cmd(f'dfu-util -S {id} -a 0 -U {f_dfu0}') assert ret.returncode == 0, 'Upload failed' - ret = subprocess.run(f'dfu-util -S {id} -a 1 -U dfu1', - shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + ret = run_cmd(f'dfu-util -S {id} -a 1 -U {f_dfu1}') assert ret.returncode == 0, 'Upload failed' - with open('dfu0') as f: + with open(f_dfu0) as f: assert 'Hello world from TinyUSB DFU! - Partition 0' in f.read(), 'Wrong uploaded data' - with open('dfu1') as f: + with open(f_dfu1) as f: assert 'Hello world from TinyUSB DFU! - Partition 1' in f.read(), 'Wrong uploaded data' - os.remove('dfu0') - os.remove('dfu1') + os.remove(f_dfu0) + os.remove(f_dfu1) def test_dfu_runtime(id): @@ -333,9 +300,9 @@ def test_hid_composite_freertos(id): all_tests = [ 'cdc_dual_ports', 'cdc_msc', - #'cdc_msc_freertos', + 'cdc_msc_freertos', 'dfu', - #'dfu_runtime', + 'dfu_runtime', 'hid_boot_interface', 'board_test' ] @@ -362,7 +329,7 @@ def test_board(item): if not os.path.exists(fw_dir): fw_dir = f'examples/cmake-build-{name}/device/{test}' fw_name = f'{fw_dir}/{test}' - print(f'{name:20} {test:20} ... ', end='') + print(f'{name:30} {test:20} ... ', end='') if not os.path.exists(fw_dir): print('Skip') -- cgit v1.3.1 From d680424f62b0d677158af7219b319a24f5497d1c Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 6 Aug 2024 22:18:25 +0700 Subject: improve dcd_int_handler() - skip DIR and use CTR TX/RX to handle complete transfer - clear CTR first, except for setup which we need to get data first - separate handle_ctr_setup() --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 238 ++++++++++++-------------- src/portable/st/stm32_fsdev/fsdev_type.h | 26 ++- 2 files changed, 132 insertions(+), 132 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 43636198a..97529997d 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -4,7 +4,6 @@ * Copyright (c) 2019 Nathan Conrad * * Portions: - * Copyright (c) 2016 STMicroelectronics * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2022 Simon Küppers (skuep) * Copyright (c) 2022 HiFiPhile @@ -215,10 +214,11 @@ void dcd_init(uint8_t rhport) { // Reset endpoints to disabled for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) { // This doesn't clear all bits since some bits are "toggle", but does set the type to DISABLED. - ep_write(i, 0u); + ep_write(i, 0u, false); } FSDEV_REG->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; + //| USB_CNTR_ERRM | USB_CNTR_PMAOVRM; handle_bus_reset(rhport); // Enable pull-up if supported @@ -274,13 +274,10 @@ static void handle_bus_reset(uint8_t rhport) { // Handle CTR interrupt for the TX/IN direction static void handle_ctr_tx(uint32_t ep_id) { - uint32_t ep_reg = ep_read(ep_id) & USB_EPREG_MASK; - - // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? - TU_VERIFY(ep_reg & USB_EP_CTR_TX, ); + uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX; + ep_reg &= USB_EPREG_MASK; uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD; - uint8_t ep_addr = (ep_reg & USB_EPADDR_FIELD) | TUSB_DIR_IN_MASK; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_IN); if (ep_is_iso(ep_reg)) { @@ -296,108 +293,72 @@ static void handle_ctr_tx(uint32_t ep_id) { } if (xfer->total_len != xfer->queued_len) { - dcd_transmit_packet(xfer, ep_id); // also clear CTR bit + dcd_transmit_packet(xfer, ep_id); } else { - dcd_event_xfer_complete(0, ep_addr, xfer->total_len, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(0, ep_num | TUSB_DIR_IN_MASK, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } +} - // Clear CTR TX and reserved CTR RX - ep_reg = (ep_reg & ~USB_EP_CTR_TX) | USB_EP_CTR_RX; +static void handle_ctr_setup(uint32_t ep_id) { + uint16_t rx_count = btable_get_count(ep_id, BTABLE_BUF_RX); + uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX); + uint8_t setup_packet[8] TU_ATTR_ALIGNED(4); - ep_write(ep_id, ep_reg); + dcd_read_packet_memory(setup_packet, rx_addr, rx_count); + + // Clear CTR RX if another setup packet arrived before this, it will be discarded + ep_write_clear_ctr(ep_id, TUSB_DIR_OUT); + + // Setup packet should always be 8 bytes. If not, we probably missed the packet + if (rx_count == 8) { + dcd_event_setup_received(0, (uint8_t*) setup_packet, true); + // Hardware should reset EP0 RX/TX to NAK and both toggle to 1 + } else { + // Missed setup packet !!! + TU_BREAKPOINT(); + edpt0_prepare_setup(); } } // Handle CTR interrupt for the RX/OUT direction static void handle_ctr_rx(uint32_t ep_id) { -#ifdef FSDEV_BUS_32BIT - /* https://www.st.com/resource/en/errata_sheet/es0561-stm32h503cbebkbrb-device-errata-stmicroelectronics.pdf - * From STM32H503 errata 2.15.1: Buffer description table update completes after CTR interrupt triggers - * Description: - * - During OUT transfers, the correct transfer interrupt (CTR) is triggered a little before the last USB SRAM accesses - * have completed. If the software responds quickly to the interrupt, the full buffer contents may not be correct. - * Workaround: - * - Software should ensure that a small delay is included before accessing the SRAM contents. This delay - * should be 800 ns in Full Speed mode and 6.4 μs in Low Speed mode - * - Since H5 can run up to 250Mhz -> 1 cycle = 4ns. Per errata, we need to wait 200 cycles. Though executing code - * also takes time, so we'll wait 60 cycles (count = 20). - * - Since Low Speed mode is not supported/popular, we will ignore it for now. - * - * Note: this errata also seems to apply to G0, U5, H5 etc. - */ - volatile uint32_t cycle_count = 20; // defined as PCD_RX_PMA_CNT in stm32 hal_driver - while (cycle_count > 0U) { - cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare) - } -#endif - - uint32_t ep_reg = ep_read(ep_id); - - // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? - TU_VERIFY(ep_reg & USB_EP_CTR_RX, ); - ep_reg = (ep_reg & ~USB_EP_CTR_RX) | USB_EP_CTR_TX; // Clear CTR RX and reserved CTR TX + uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX; + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_OUT); // will change RX Status, reserved other toggle bits uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD; + bool const is_iso = ep_is_iso(ep_reg); + xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT); - if (ep_reg & USB_EP_SETUP) { - uint32_t count = btable_get_count(ep_id, BTABLE_BUF_RX); - // Setup packet should always be 8 bytes. If not, ignore it, and try again. - if (count == 8) { - uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX); - uint8_t setup_packet[8] TU_ATTR_ALIGNED(4); - - dcd_read_packet_memory(setup_packet, rx_addr, 8); - dcd_event_setup_received(0, (uint8_t*) setup_packet, true); - - // Reset EP to NAK and set both toggle to 1 - ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); - ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); - ep_add_dtog(&ep_reg, TUSB_DIR_IN, 1); - ep_add_dtog(&ep_reg, TUSB_DIR_OUT, 1); - } else { - // Missed an setup packet !!! - TU_BREAKPOINT(); - ep_reg &= USB_EPREG_MASK; // reversed all toggle - edpt0_prepare_setup(); - } + uint8_t buf_id; + if (is_iso) { + buf_id = (ep_reg & USB_EP_DTOG_RX) ? 0 : 1; // ISO are double buffered } else { - ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_OUT); // reversed all toggle except RX Status - - bool const is_iso = ep_is_iso(ep_reg); - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT); + buf_id = BTABLE_BUF_RX; + } + uint16_t const rx_count = btable_get_count(ep_id, buf_id); + uint16_t pma_addr = (uint16_t) btable_get_addr(ep_id, buf_id); - uint8_t buf_id; - if (is_iso) { - buf_id = (ep_reg & USB_EP_DTOG_RX) ? 0 : 1; // ISO are double buffered + if (rx_count != 0) { + if (xfer->ff) { + dcd_read_packet_memory_ff(xfer->ff, pma_addr, rx_count); } else { - buf_id = BTABLE_BUF_RX; - } - uint32_t rx_count = btable_get_count(ep_id, buf_id); - uint16_t pma_addr = (uint16_t) btable_get_addr(ep_id, buf_id); - - if (rx_count != 0) { - if (xfer->ff) { - dcd_read_packet_memory_ff(xfer->ff, pma_addr, rx_count); - } else { - dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); - } - xfer->queued_len = (uint16_t)(xfer->queued_len + rx_count); + dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); } + xfer->queued_len += rx_count; + } - if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { - // all bytes received or short packet - ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); - dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); - } else { - // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always - if (!is_iso) { - uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); - btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); - } - ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); + if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { + // all bytes received or short packet + dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } else { + // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always + if (!is_iso) { + uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); + btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); } + ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); + ep_write(ep_id, ep_reg, false); } - - ep_write(ep_id, ep_reg); } void dcd_int_handler(uint8_t rhport) { @@ -406,10 +367,6 @@ void dcd_int_handler(uint8_t rhport) { // | USB_ISTR_SUSP | USB_ISTR_SOF | USB_ISTR_ESOF; // unused IRQs: (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_L1REQ ) - // The ST driver loops here on the CTR bit, but that loop has been moved into the - // dcd_ep_ctr_handler(), so less need to loop here. The other interrupts shouldn't - // be triggered repeatedly. - /* Put SOF flag at the beginning of ISR in case to get least amount of jitter if it is used for timing purposes */ if (int_status & USB_ISTR_SOF) { FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_SOF; @@ -455,17 +412,51 @@ void dcd_int_handler(uint8_t rhport) { FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF; } +// if (int_status & (USB_ISTR_ERR | USB_ISTR_PMAOVR)) { +// TU_BREAKPOINT(); +// } + // loop to handle all pending CTR interrupts - while (int_status & USB_ISTR_CTR) { - uint32_t const ep_id = int_status & USB_ISTR_EP_ID; + while (FSDEV_REG->ISTR & USB_ISTR_CTR) { + // skip DIR bit, and use CTR TX/RX instead, since there is chance we have both TX/RX completed in one interrupt + uint32_t const ep_id = FSDEV_REG->ISTR & USB_ISTR_EP_ID; + uint32_t const ep_reg = ep_read(ep_id); + + if (ep_reg & USB_EP_CTR_RX) { + #ifdef FSDEV_BUS_32BIT + /* https://www.st.com/resource/en/errata_sheet/es0561-stm32h503cbebkbrb-device-errata-stmicroelectronics.pdf + * https://www.st.com/resource/en/errata_sheet/es0587-stm32u535xx-and-stm32u545xx-device-errata-stmicroelectronics.pdf + * From H503/U535 errata: Buffer description table update completes after CTR interrupt triggers + * Description: + * - During OUT transfers, the correct transfer interrupt (CTR) is triggered a little before the last USB SRAM accesses + * have completed. If the software responds quickly to the interrupt, the full buffer contents may not be correct. + * Workaround: + * - Software should ensure that a small delay is included before accessing the SRAM contents. This delay + * should be 800 ns in Full Speed mode and 6.4 μs in Low Speed mode + * - Since H5 can run up to 250Mhz -> 1 cycle = 4ns. Per errata, we need to wait 200 cycles. Though executing code + * also takes time, so we'll wait 60 cycles (count = 20). + * - Since Low Speed mode is not supported/popular, we will ignore it for now. + * + * Note: this errata may also apply to G0, U5, H5 etc. + */ + volatile uint32_t cycle_count = 20; // defined as PCD_RX_PMA_CNT in stm32 hal_driver + while (cycle_count > 0U) { + cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare) + } + #endif - if ((int_status & USB_ISTR_DIR) == 0U) { - handle_ctr_tx(ep_id); // TX/IN - } else { - handle_ctr_rx(ep_id); // RX/OUT or both (RX/TX !!) + if (ep_reg & USB_EP_SETUP) { + handle_ctr_setup(ep_id); + } else { + ep_write_clear_ctr(ep_id, TUSB_DIR_OUT); + handle_ctr_rx(ep_id); + } } - int_status = FSDEV_REG->ISTR; + if (ep_reg & USB_EP_CTR_TX) { + ep_write_clear_ctr(ep_id, TUSB_DIR_IN); + handle_ctr_tx(ep_id); + } } } @@ -577,7 +568,7 @@ void edpt0_open(uint8_t rhport) { // no need to explicitly set DTOG bits since we aren't masked DTOG bit edpt0_prepare_setup(); // prepare for setup packet - ep_write(0, ep_reg); + ep_write(0, ep_reg, false); } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { @@ -590,7 +581,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { TU_ASSERT(ep_idx < FSDEV_EP_COUNT); uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK; - ep_reg |= tu_edpt_number(ep_addr) | USB_EP_CTR_RX | USB_EP_CTR_TX; + ep_reg |= tu_edpt_number(ep_addr) | USB_EP_CTR_TX | USB_EP_CTR_RX; // Set type switch (desc_ep->bmAttributes.xfer) { @@ -624,18 +615,17 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX); } - ep_write(ep_idx, ep_reg); + ep_write(ep_idx, ep_reg, true); return true; } -void dcd_edpt_close_all(uint8_t rhport) -{ - (void)rhport; +void dcd_edpt_close_all(uint8_t rhport) { + dcd_int_disable(rhport); for (uint32_t i = 1; i < FSDEV_EP_COUNT; i++) { // Reset endpoint - ep_write(i, 0); + ep_write(i, 0, false); // Clear EP allocation status ep_alloc_status[i].ep_num = 0xFF; ep_alloc_status[i].ep_type = 0xFF; @@ -643,6 +633,8 @@ void dcd_edpt_close_all(uint8_t rhport) ep_alloc_status[i].allocated[1] = false; } + dcd_int_enable(rhport); + // Reset PMA allocation ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE; } @@ -684,13 +676,13 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) xfer->max_packet_size = tu_edpt_packet_size(desc_ep); uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK; - ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX; + ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_TX | USB_EP_CTR_RX; ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); ep_add_dtog(&ep_reg, dir, 0); ep_add_dtog(&ep_reg, 1-dir, 1); - ep_write(ep_idx, ep_reg); + ep_write(ep_idx, ep_reg, true); return true; } @@ -698,7 +690,9 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) // Currently, single-buffered, and only 64 bytes at a time (max) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); - uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits + uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR RX + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); // only change TX Status, reserve other toggle bits + bool const is_iso = ep_is_iso(ep_reg); uint8_t buf_id; @@ -715,21 +709,16 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { } else { dcd_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len); } - xfer->queued_len = (uint16_t) (xfer->queued_len + len); + xfer->queued_len += len; } btable_set_count(ep_ix, buf_id, len); - - ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_VALID); - ep_clear_ctr(&ep_reg, TUSB_DIR_IN); - dcd_int_disable(0); - ep_write(ep_ix, ep_reg); if (is_iso) { xfer->iso_in_sending = true; } - dcd_int_enable(0); + ep_write(ep_ix, ep_reg, true); } static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { @@ -741,8 +730,8 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { if (dir == TUSB_DIR_IN) { dcd_transmit_packet(xfer, ep_idx); } else { - uint32_t cnt = (uint32_t) tu_min16(xfer->total_len, xfer->max_packet_size); - uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX; // keep CTR TX, clear CTR RX + uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); + uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // keep CTR TX ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); ep_add_status(&ep_reg, dir, EP_STAT_VALID); @@ -753,7 +742,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); } - ep_write(ep_idx, ep_reg); + ep_write(ep_idx, ep_reg, true); } return true; @@ -796,7 +785,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); ep_add_status(&ep_reg, dir, EP_STAT_STALL); - ep_write(ep_idx, ep_reg); + ep_write(ep_idx, ep_reg, true); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { @@ -814,8 +803,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { ep_add_status(&ep_reg, dir, EP_STAT_NAK); } ep_add_dtog(&ep_reg, dir, 0); // Reset to DATA0 - - ep_write(ep_idx, ep_reg); + ep_write(ep_idx, ep_reg, true); } // Write to packet memory area (PMA) from user memory diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index 8432df4b0..f29abd703 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -172,8 +172,24 @@ typedef enum { // - DTOG and STAT are write 1 to toggle //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value) { +TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value, bool need_exclusive) { + if (need_exclusive) { + dcd_int_disable(0); + } + FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; + + if (need_exclusive) { + dcd_int_enable(0); + } +} + +TU_ATTR_ALWAYS_INLINE static inline void ep_write_clear_ctr(uint32_t ep_id, tusb_dir_t dir) { + uint32_t reg = FSDEV_REG->ep[ep_id].reg; + reg |= USB_EP_CTR_TX | USB_EP_CTR_RX; + reg &= USB_EPREG_MASK; + reg &= ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); + ep_write(ep_id, reg, false); } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { @@ -188,10 +204,6 @@ TU_ATTR_ALWAYS_INLINE static inline void ep_add_dtog(uint32_t* reg, tusb_dir_t d *reg ^= (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -TU_ATTR_ALWAYS_INLINE static inline void ep_clear_ctr(uint32_t* reg, tusb_dir_t dir) { - *reg &= ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); -} - TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; } @@ -218,7 +230,7 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t #endif } -TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { +TU_ATTR_ALWAYS_INLINE static inline uint16_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { uint16_t count; #ifdef FSDEV_BUS_32BIT count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16); @@ -258,7 +270,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t pma_align_buffer_size(uint16_t size return (*num_block) * block_in_bytes; } -TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint32_t wCount) { +TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint16_t wCount) { uint8_t blsize, num_block; (void) pma_align_buffer_size(wCount, &blsize, &num_block); -- cgit v1.3.1 From 0860cd3b5e95a7366bc2c68eb7648e8479059172 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 6 Aug 2024 22:20:24 +0700 Subject: minor rename --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 28 +++++++++++++-------------- src/portable/st/stm32_fsdev/fsdev_type.h | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 97529997d..2075babe3 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -356,7 +356,7 @@ static void handle_ctr_rx(uint32_t ep_id) { uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); } - ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); + ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); ep_write(ep_id, ep_reg, false); } } @@ -563,8 +563,8 @@ void edpt0_open(uint8_t rhport) { uint32_t ep_reg = ep_read(0) & ~USB_EPREG_MASK; // only get toggle bits ep_reg |= USB_EP_CONTROL; - ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); - ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); + ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); + ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); // no need to explicitly set DTOG bits since we aren't masked DTOG bit edpt0_prepare_setup(); // prepare for setup packet @@ -605,8 +605,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { xfer->max_packet_size = packet_size; xfer->ep_idx = ep_idx; - ep_add_status(&ep_reg, dir, EP_STAT_NAK); - ep_add_dtog(&ep_reg, dir, 0); + ep_change_status(&ep_reg, dir, EP_STAT_NAK); + ep_change_dtog(&ep_reg, dir, 0); // reserve other direction toggle bits if (dir == TUSB_DIR_IN) { @@ -677,10 +677,10 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK; ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_TX | USB_EP_CTR_RX; - ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); - ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); - ep_add_dtog(&ep_reg, dir, 0); - ep_add_dtog(&ep_reg, 1-dir, 1); + ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); + ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); + ep_change_dtog(&ep_reg, dir, 0); + ep_change_dtog(&ep_reg, 1 - dir, 1); ep_write(ep_idx, ep_reg, true); @@ -713,7 +713,7 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { } btable_set_count(ep_ix, buf_id, len); - ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_VALID); + ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_VALID); if (is_iso) { xfer->iso_in_sending = true; @@ -733,7 +733,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // keep CTR TX ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); - ep_add_status(&ep_reg, dir, EP_STAT_VALID); + ep_change_status(&ep_reg, dir, EP_STAT_VALID); if (ep_is_iso(ep_reg)) { btable_set_rx_bufsize(ep_idx, 0, cnt); @@ -783,7 +783,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); - ep_add_status(&ep_reg, dir, EP_STAT_STALL); + ep_change_status(&ep_reg, dir, EP_STAT_STALL); ep_write(ep_idx, ep_reg, true); } @@ -800,9 +800,9 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); if (!ep_is_iso(ep_reg)) { - ep_add_status(&ep_reg, dir, EP_STAT_NAK); + ep_change_status(&ep_reg, dir, EP_STAT_NAK); } - ep_add_dtog(&ep_reg, dir, 0); // Reset to DATA0 + ep_change_dtog(&ep_reg, dir, 0); // Reset to DATA0 ep_write(ep_idx, ep_reg, true); } diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index f29abd703..d5028c702 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -196,11 +196,11 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { return FSDEV_REG->ep[ep_id].reg; } -TU_ATTR_ALWAYS_INLINE static inline void ep_add_status(uint32_t* reg, tusb_dir_t dir, ep_stat_t state) { +TU_ATTR_ALWAYS_INLINE static inline void ep_change_status(uint32_t* reg, tusb_dir_t dir, ep_stat_t state) { *reg ^= (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -TU_ATTR_ALWAYS_INLINE static inline void ep_add_dtog(uint32_t* reg, tusb_dir_t dir, uint8_t state) { +TU_ATTR_ALWAYS_INLINE static inline void ep_change_dtog(uint32_t* reg, tusb_dir_t dir, uint8_t state) { *reg ^= (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -- cgit v1.3.1 From 3a2216306769f0af0ceb3dde7528dfb182fec8f5 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 7 Aug 2024 15:16:22 +0700 Subject: fix v203 race condition between rx bufsize and RX_STAT which cause PMAOVR fix set_rx_bufsize with invalid value for zero length packet --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 28 ++++++++++++++++----------- src/portable/st/stm32_fsdev/fsdev_type.h | 17 ++++++++++------ 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 2075babe3..cd7410488 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -217,8 +217,8 @@ void dcd_init(uint8_t rhport) { ep_write(i, 0u, false); } - FSDEV_REG->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; - //| USB_CNTR_ERRM | USB_CNTR_PMAOVRM; + FSDEV_REG->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | + USB_CNTR_SUSPM | USB_CNTR_WKUPM | USB_CNTR_PMAOVRM; handle_bus_reset(rhport); // Enable pull-up if supported @@ -349,6 +349,10 @@ static void handle_ctr_rx(uint32_t ep_id) { if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { // all bytes received or short packet + + // reset rx bufsize to mps to prevent race condition to cause PMAOVR (occurs with ch32v203 with msc write10) + btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, xfer->max_packet_size); + dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); } else { // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always @@ -412,9 +416,10 @@ void dcd_int_handler(uint8_t rhport) { FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF; } -// if (int_status & (USB_ISTR_ERR | USB_ISTR_PMAOVR)) { -// TU_BREAKPOINT(); -// } + if (int_status & USB_ISTR_PMAOVR) { + TU_BREAKPOINT(); + FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_PMAOVR; + } // loop to handle all pending CTR interrupts while (FSDEV_REG->ISTR & USB_ISTR_CTR) { @@ -446,7 +451,7 @@ void dcd_int_handler(uint8_t rhport) { #endif if (ep_reg & USB_EP_SETUP) { - handle_ctr_setup(ep_id); + handle_ctr_setup(ep_id); // CTR will be clear after copied setup packet } else { ep_write_clear_ctr(ep_id, TUSB_DIR_OUT); handle_ctr_rx(ep_id); @@ -690,7 +695,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) // Currently, single-buffered, and only 64 bytes at a time (max) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); - uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR RX + uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); // only change TX Status, reserve other toggle bits bool const is_iso = ep_is_iso(ep_reg); @@ -730,10 +735,10 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { if (dir == TUSB_DIR_IN) { dcd_transmit_packet(xfer, ep_idx); } else { - uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); - uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // keep CTR TX + uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); - ep_change_status(&ep_reg, dir, EP_STAT_VALID); + + uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); if (ep_is_iso(ep_reg)) { btable_set_rx_bufsize(ep_idx, 0, cnt); @@ -742,7 +747,8 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); } - ep_write(ep_idx, ep_reg, true); + ep_change_status(&ep_reg, dir, EP_STAT_VALID); + ep_write(ep_idx, ep_reg, false); } return true; diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index d5028c702..6c5ccae89 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -172,6 +172,10 @@ typedef enum { // - DTOG and STAT are write 1 to toggle //--------------------------------------------------------------------+ +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { + return FSDEV_REG->ep[ep_id].reg; +} + TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value, bool need_exclusive) { if (need_exclusive) { dcd_int_disable(0); @@ -192,10 +196,6 @@ TU_ATTR_ALWAYS_INLINE static inline void ep_write_clear_ctr(uint32_t ep_id, tusb ep_write(ep_id, reg, false); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { - return FSDEV_REG->ep[ep_id].reg; -} - TU_ATTR_ALWAYS_INLINE static inline void ep_change_status(uint32_t* reg, tusb_dir_t dir, ep_stat_t state) { *reg ^= (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } @@ -260,13 +260,13 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t pma_align_buffer_size(uint16_t size if (size > 62) { block_in_bytes = 32; *blsize = 1; + *num_block = tu_div_ceil(size, 32); } else { block_in_bytes = 2; *blsize = 0; + *num_block = tu_div_ceil(size, 2); } - *num_block = tu_div_ceil(size, block_in_bytes); - return (*num_block) * block_in_bytes; } @@ -276,6 +276,10 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10); + if (bl_nb == 0) { + // 0 is invalid, set up blsize to 1 + bl_nb = 1 << 15; + } #ifdef FSDEV_BUS_32BIT uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; @@ -284,6 +288,7 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u #else FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb; #endif + } #ifdef __cplusplus -- cgit v1.3.1 From 57c26fdc72dccee1da569e90f46b4060a97d47a7 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 8 Aug 2024 00:27:51 +0700 Subject: use EP_KIND for STATUS OUT to fix OUT packet is auto accepted after SETUP without usbd consent --- .idea/cmake.xml | 15 +++++------ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 36 +++++++++++++++++---------- src/portable/st/stm32_fsdev/fsdev_type.h | 4 +-- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 67e793016..bf5696725 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -89,19 +89,20 @@ - - + + + - + - + - + @@ -133,8 +134,8 @@ - - + + diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index cd7410488..89697106d 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -147,6 +147,7 @@ typedef struct { static xfer_ctl_t xfer_status[CFG_TUD_ENDPPOINT_MAX][2]; static ep_alloc_t ep_alloc_status[FSDEV_EP_COUNT]; static uint8_t remoteWakeCountdown; // When wake is requested +static uint8_t _setup_dir; // for detecting status OUT //--------------------------------------------------------------------+ // Prototypes @@ -311,6 +312,7 @@ static void handle_ctr_setup(uint32_t ep_id) { // Setup packet should always be 8 bytes. If not, we probably missed the packet if (rx_count == 8) { + _setup_dir = (setup_packet[0] & 0x80 ? TUSB_DIR_IN : TUSB_DIR_OUT); dcd_event_setup_received(0, (uint8_t*) setup_packet, true); // Hardware should reset EP0 RX/TX to NAK and both toggle to 1 } else { @@ -323,8 +325,6 @@ static void handle_ctr_setup(uint32_t ep_id) { // Handle CTR interrupt for the RX/OUT direction static void handle_ctr_rx(uint32_t ep_id) { uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX; - ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_OUT); // will change RX Status, reserved other toggle bits - uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD; bool const is_iso = ep_is_iso(ep_reg); xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT); @@ -345,6 +345,13 @@ static void handle_ctr_rx(uint32_t ep_id) { dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); } xfer->queued_len += rx_count; + } else { + // ZLP Status OUT + if (ep_num == 0 && (ep_reg & USB_EP_KIND) ) { + ep_reg &= USB_EPREG_MASK; + ep_reg &= ~USB_EP_KIND; // clear kind bit + ep_write(ep_id, ep_reg, false); + } } if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { @@ -360,6 +367,7 @@ static void handle_ctr_rx(uint32_t ep_id) { uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); } + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_OUT); // will change RX Status, reserved other toggle bits ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); ep_write(ep_id, ep_reg, false); } @@ -367,9 +375,6 @@ static void handle_ctr_rx(uint32_t ep_id) { void dcd_int_handler(uint8_t rhport) { uint32_t int_status = FSDEV_REG->ISTR; - // const uint32_t handled_ints = USB_ISTR_CTR | USB_ISTR_RESET | USB_ISTR_WKUP - // | USB_ISTR_SUSP | USB_ISTR_SOF | USB_ISTR_ESOF; - // unused IRQs: (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_L1REQ ) /* Put SOF flag at the beginning of ISR in case to get least amount of jitter if it is used for timing purposes */ if (int_status & USB_ISTR_SOF) { @@ -738,17 +743,22 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); - uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); - - if (ep_is_iso(ep_reg)) { - btable_set_rx_bufsize(ep_idx, 0, cnt); - btable_set_rx_bufsize(ep_idx, 1, cnt); + if ( ep_num == 0 && dir == TUSB_DIR_OUT && _setup_dir == TUSB_DIR_IN ) { + // use EP0 OUT status stage, otherwise OUT packet right after SETUP will be accepted without + // the usbd (software) consent + ep_reg |= USB_EP_KIND; } else { - btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); - } + uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); + if (ep_is_iso(ep_reg)) { + btable_set_rx_bufsize(ep_idx, 0, cnt); + btable_set_rx_bufsize(ep_idx, 1, cnt); + } else { + btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); + } + } ep_change_status(&ep_reg, dir, EP_STAT_VALID); - ep_write(ep_idx, ep_reg, false); + ep_write(ep_idx, ep_reg, true); } return true; diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index 6c5ccae89..7ebc32255 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -277,8 +277,8 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10); if (bl_nb == 0) { - // 0 is invalid, set up blsize to 1 - bl_nb = 1 << 15; + // zlp but 0 is invalid value, set num_block to 1 (2 bytes) + bl_nb = 1 << 10; } #ifdef FSDEV_BUS_32BIT -- cgit v1.3.1 From bd64625df271c461c3d6008f96c630c61218f451 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 8 Aug 2024 12:40:11 +0700 Subject: revert the use of EP_KIND. ch32v203 seems to unconditionally accept ZLP on EP0 OUT, which can incorrectly use queued_len of previous transfer. So reset total_len and queued_len to 0. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 38 +++++++++------------------ 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 89697106d..bbdfbaa09 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -147,7 +147,6 @@ typedef struct { static xfer_ctl_t xfer_status[CFG_TUD_ENDPPOINT_MAX][2]; static ep_alloc_t ep_alloc_status[FSDEV_EP_COUNT]; static uint8_t remoteWakeCountdown; // When wake is requested -static uint8_t _setup_dir; // for detecting status OUT //--------------------------------------------------------------------+ // Prototypes @@ -312,7 +311,6 @@ static void handle_ctr_setup(uint32_t ep_id) { // Setup packet should always be 8 bytes. If not, we probably missed the packet if (rx_count == 8) { - _setup_dir = (setup_packet[0] & 0x80 ? TUSB_DIR_IN : TUSB_DIR_OUT); dcd_event_setup_received(0, (uint8_t*) setup_packet, true); // Hardware should reset EP0 RX/TX to NAK and both toggle to 1 } else { @@ -345,22 +343,17 @@ static void handle_ctr_rx(uint32_t ep_id) { dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); } xfer->queued_len += rx_count; - } else { - // ZLP Status OUT - if (ep_num == 0 && (ep_reg & USB_EP_KIND) ) { - ep_reg &= USB_EPREG_MASK; - ep_reg &= ~USB_EP_KIND; // clear kind bit - ep_write(ep_id, ep_reg, false); - } } - if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { + if ((rx_count < xfer->max_packet_size) || (xfer->queued_len >= xfer->total_len)) { // all bytes received or short packet + dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); - // reset rx bufsize to mps to prevent race condition to cause PMAOVR (occurs with ch32v203 with msc write10) + // For ch32v203: reset rx bufsize to mps to prevent race condition to cause PMAOVR (occurs with msc write10) + // also ch32 seems to unconditionally accept ZLP on EP0 OUT, which can incorrectly use queued_len of previous + // transfer. So reset total_len and queued_len to 0. btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, xfer->max_packet_size); - - dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); + xfer->total_len = xfer->queued_len = 0; } else { // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always if (!is_iso) { @@ -743,20 +736,15 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); - if ( ep_num == 0 && dir == TUSB_DIR_OUT && _setup_dir == TUSB_DIR_IN ) { - // use EP0 OUT status stage, otherwise OUT packet right after SETUP will be accepted without - // the usbd (software) consent - ep_reg |= USB_EP_KIND; - } else { - uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); + uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); - if (ep_is_iso(ep_reg)) { - btable_set_rx_bufsize(ep_idx, 0, cnt); - btable_set_rx_bufsize(ep_idx, 1, cnt); - } else { - btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); - } + if (ep_is_iso(ep_reg)) { + btable_set_rx_bufsize(ep_idx, 0, cnt); + btable_set_rx_bufsize(ep_idx, 1, cnt); + } else { + btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); } + ep_change_status(&ep_reg, dir, EP_STAT_VALID); ep_write(ep_idx, ep_reg, true); } -- cgit v1.3.1 From 1ea38ebe13f07c4db99ae39f207e55815d3701b3 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 8 Aug 2024 15:43:11 +0700 Subject: refactor read/write pma from/to fifo --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 247 ++++++++++---------------- src/portable/st/stm32_fsdev/fsdev_type.h | 8 + 2 files changed, 98 insertions(+), 157 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index bbdfbaa09..252969648 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -336,14 +336,12 @@ static void handle_ctr_rx(uint32_t ep_id) { uint16_t const rx_count = btable_get_count(ep_id, buf_id); uint16_t pma_addr = (uint16_t) btable_get_addr(ep_id, buf_id); - if (rx_count != 0) { - if (xfer->ff) { - dcd_read_packet_memory_ff(xfer->ff, pma_addr, rx_count); - } else { - dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); - } - xfer->queued_len += rx_count; + if (xfer->ff) { + dcd_read_packet_memory_ff(xfer->ff, pma_addr, rx_count); + } else { + dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); } + xfer->queued_len += rx_count; if ((rx_count < xfer->max_packet_size) || (xfer->queued_len >= xfer->total_len)) { // all bytes received or short packet @@ -706,14 +704,12 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { } uint16_t addr_ptr = (uint16_t) btable_get_addr(ep_ix, buf_id); - if (len) { - if (xfer->ff) { - dcd_write_packet_memory_ff(xfer->ff, addr_ptr, len); - } else { - dcd_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len); - } - xfer->queued_len += len; + if (xfer->ff) { + dcd_write_packet_memory_ff(xfer->ff, addr_ptr, len); + } else { + dcd_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len); } + xfer->queued_len += len; btable_set_count(ep_ix, buf_id, len); ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_VALID); @@ -814,25 +810,20 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { // - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT // - Uses unaligned for RAM (since M0 cannot access unaligned address) static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) { - enum { BUS_SIZE = sizeof(fsdev_bus_t) }; - uint32_t n_write = nbytes / BUS_SIZE; + if (nbytes == 0) return true; + uint32_t n_write = nbytes / FSDEV_BUS_SIZE; fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(dst); const uint8_t *src8 = src; while (n_write--) { - #ifdef FSDEV_BUS_32BIT - pma_buf->value = tu_unaligned_read32(src8); - #else - pma_buf->value = tu_unaligned_read16(src8); - #endif - - src8 += BUS_SIZE; + pma_buf->value = fsdevbus_unaligned_read(src8); + src8 += FSDEV_BUS_SIZE; pma_buf++; } // odd bytes e.g 1 for 16-bit or 1-3 for 32-bit - uint16_t odd = nbytes & (BUS_SIZE - 1); + uint16_t odd = nbytes & (FSDEV_BUS_SIZE - 1); if (odd) { fsdev_bus_t temp = 0; for(uint16_t i = 0; i < odd; i++) { @@ -848,27 +839,20 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui // - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT // - Uses unaligned for RAM (since M0 cannot access unaligned address) static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) { - enum { BUS_SIZE = sizeof(fsdev_bus_t) }; - uint32_t n_write = nbytes / BUS_SIZE; + if (nbytes == 0) return true; + uint32_t n_read = nbytes / FSDEV_BUS_SIZE; fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(src); uint8_t *dst8 = (uint8_t *)dst; - while (n_write--) { - fsdev_bus_t temp = pma_buf->value; - - #ifdef FSDEV_BUS_32BIT - tu_unaligned_write32(dst8, temp); - #else - tu_unaligned_write16(dst8, temp); - #endif - - dst8 += BUS_SIZE; + while (n_read--) { + fsdevbus_unaligned_write(dst8, (fsdev_bus_t ) pma_buf->value); + dst8 += FSDEV_BUS_SIZE; pma_buf++; } // odd bytes e.g 1 for 16-bit or 1-3 for 32-bit - uint16_t odd = nbytes & (BUS_SIZE - 1); + uint16_t odd = nbytes & (FSDEV_BUS_SIZE - 1); if (odd) { fsdev_bus_t temp = pma_buf->value; while (odd--) { @@ -880,156 +864,105 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t return true; } -/** - * @brief Copy from FIFO to packet memory area (PMA). - * Uses byte-access of system memory and 16-bit access of packet memory - * @param wNBytes no. of bytes to be copied. - * @retval None - */ +// Write to PMA from FIFO static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes) { + if (wNBytes == 0) return true; + // Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies tu_fifo_buffer_info_t info; tu_fifo_get_read_info(ff, &info); - uint16_t cnt_lin = TU_MIN(wNBytes, info.len_lin); - uint16_t cnt_wrap = TU_MIN(wNBytes - cnt_lin, info.len_wrap); + uint16_t cnt_lin = tu_min16(wNBytes, info.len_lin); + uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.len_wrap); + uint16_t const cnt_total = cnt_lin + cnt_wrap; // We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part, - // last lin byte will be combined with wrapped part - // To ensure PMA is always access aligned (dst aligned to 16 or 32 bit) -#ifdef FSDEV_BUS_32BIT - if ((cnt_lin & 0x03) && cnt_wrap) { - // Copy first linear part - dcd_write_packet_memory(dst, info.ptr_lin, cnt_lin & ~0x03); - dst += cnt_lin & ~0x03; - - // Copy last linear bytes & first wrapped bytes to buffer - uint32_t i; - uint8_t tmp[4]; - for (i = 0; i < (cnt_lin & 0x03); i++) { - tmp[i] = ((uint8_t *)info.ptr_lin)[(cnt_lin & ~0x03) + i]; - } - uint32_t wCnt = cnt_wrap; - for (; i < 4 && wCnt > 0; i++, wCnt--) { - tmp[i] = *(uint8_t *)info.ptr_wrap; - info.ptr_wrap = (uint8_t *)info.ptr_wrap + 1; + // last lin byte will be combined with wrapped part To ensure PMA is always access aligned + uint16_t lin_even = cnt_lin & ~(FSDEV_BUS_SIZE - 1); + uint16_t lin_odd = cnt_lin & (FSDEV_BUS_SIZE - 1); + uint8_t const *src8 = (uint8_t const*) info.ptr_lin; + + // write even linear part + dcd_write_packet_memory(dst, src8, lin_even); + dst += lin_even; + src8 += lin_even; + + if (lin_odd == 0) { + src8 = (uint8_t const*) info.ptr_wrap; + } else { + // Combine last linear bytes + first wrapped bytes to form fsdev bus width data + fsdev_bus_t temp = 0; + uint16_t i; + for(i = 0; i < lin_odd; i++) { + temp |= *src8++ << (i * 8); } - // Write unaligned buffer - dcd_write_packet_memory(dst, &tmp, 4); - dst += 4; - - // Copy rest of wrapped byte - if (wCnt) { - dcd_write_packet_memory(dst, info.ptr_wrap, wCnt); - } - } -#else - if ((cnt_lin & 0x01) && cnt_wrap) { - // Copy first linear part - dcd_write_packet_memory(dst, info.ptr_lin, cnt_lin & ~0x01); - dst += cnt_lin & ~0x01; - - // Copy last linear byte & first wrapped byte - uint16_t tmp = ((uint8_t *)info.ptr_lin)[cnt_lin - 1] | ((uint16_t)(((uint8_t *)info.ptr_wrap)[0]) << 8U); - dcd_write_packet_memory(dst, &tmp, 2); - dst += 2; - - // Copy rest of wrapped byte - dcd_write_packet_memory(dst, ((uint8_t *)info.ptr_wrap) + 1, cnt_wrap - 1); - } -#endif - else { - // Copy linear part - dcd_write_packet_memory(dst, info.ptr_lin, cnt_lin); - dst += info.len_lin; - - if (info.len_wrap) { - // Copy wrapped byte - dcd_write_packet_memory(dst, info.ptr_wrap, cnt_wrap); + src8 = (uint8_t const*) info.ptr_wrap; + for(; i < FSDEV_BUS_SIZE && cnt_wrap > 0; i++, cnt_wrap--) { + temp |= *src8++ << (i * 8); } + + dcd_write_packet_memory(dst, &temp, FSDEV_BUS_SIZE); + dst += FSDEV_BUS_SIZE; } - tu_fifo_advance_read_pointer(ff, cnt_lin + cnt_wrap); + // write the rest of the wrapped part + dcd_write_packet_memory(dst, src8, cnt_wrap); + tu_fifo_advance_read_pointer(ff, cnt_total); return true; } -/** - * @brief Copy a buffer from user packet memory area (PMA) to FIFO. - * Uses byte-access of system memory and 16-bit access of packet memory - * @param wNBytes no. of bytes to be copied. - * @retval None - */ +// Read from PMA to FIFO static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes) { + if (wNBytes == 0) return true; + // Since we copy into a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies // Check for first linear part tu_fifo_buffer_info_t info; tu_fifo_get_write_info(ff, &info); // We want to read from the FIFO - uint16_t cnt_lin = TU_MIN(wNBytes, info.len_lin); - uint16_t cnt_wrap = TU_MIN(wNBytes - cnt_lin, info.len_wrap); - - // We want to read from PMA and write it into the FIFO, if LIN part is ODD and has WRAPPED part, - // last lin byte will be combined with wrapped part - // To ensure PMA is always access aligned (src aligned to 16 or 32 bit) -#ifdef FSDEV_BUS_32BIT - if ((cnt_lin & 0x03) && cnt_wrap) { - // Copy first linear part - dcd_read_packet_memory(info.ptr_lin, src, cnt_lin & ~0x03); - src += cnt_lin & ~0x03; - - // Copy last linear bytes & first wrapped bytes - uint8_t tmp[4]; - dcd_read_packet_memory(tmp, src, 4); - src += 4; - - uint32_t i; - for (i = 0; i < (cnt_lin & 0x03); i++) { - ((uint8_t *)info.ptr_lin)[(cnt_lin & ~0x03) + i] = tmp[i]; - } - uint32_t wCnt = cnt_wrap; - for (; i < 4 && wCnt > 0; i++, wCnt--) { - *(uint8_t *)info.ptr_wrap = tmp[i]; - info.ptr_wrap = (uint8_t *)info.ptr_wrap + 1; - } + uint16_t cnt_lin = tu_min16(wNBytes, info.len_lin); + uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.len_wrap); + uint16_t cnt_total = cnt_lin + cnt_wrap; - // Copy rest of wrapped byte - if (wCnt) { - dcd_read_packet_memory(info.ptr_wrap, src, wCnt); - } - } -#else - if ((cnt_lin & 0x01) && cnt_wrap) { - // Copy first linear part - dcd_read_packet_memory(info.ptr_lin, src, cnt_lin & ~0x01); - src += cnt_lin & ~0x01; + // We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part, + // last lin byte will be combined with wrapped part To ensure PMA is always access aligned - // Copy last linear byte & first wrapped byte - uint8_t tmp[2]; - dcd_read_packet_memory(tmp, src, 2); - src += 2; + uint16_t lin_even = cnt_lin & ~(FSDEV_BUS_SIZE - 1); + uint16_t lin_odd = cnt_lin & (FSDEV_BUS_SIZE - 1); + uint8_t *dst8 = (uint8_t *) info.ptr_lin; - ((uint8_t *)info.ptr_lin)[cnt_lin - 1] = tmp[0]; - ((uint8_t *)info.ptr_wrap)[0] = tmp[1]; + // read even linear part + dcd_read_packet_memory(dst8, src, lin_even); + dst8 += lin_even; + src += lin_even; - // Copy rest of wrapped byte - dcd_read_packet_memory(((uint8_t *)info.ptr_wrap) + 1, src, cnt_wrap - 1); - } -#endif - else { - // Copy linear part - dcd_read_packet_memory(info.ptr_lin, src, cnt_lin); - src += cnt_lin; - - if (info.len_wrap) { - // Copy wrapped byte - dcd_read_packet_memory(info.ptr_wrap, src, cnt_wrap); + if (lin_odd == 0) { + dst8 = (uint8_t *) info.ptr_wrap; + } else { + // Combine last linear bytes + first wrapped bytes to form fsdev bus width data + fsdev_bus_t temp; + dcd_read_packet_memory(&temp, src, FSDEV_BUS_SIZE); + src += FSDEV_BUS_SIZE; + + uint16_t i; + for (i = 0; i < lin_odd; i++) { + *dst8++ = (uint8_t) (temp & 0xfful); + temp >>= 8; + } + + dst8 = (uint8_t *) info.ptr_wrap; + for (; i < FSDEV_BUS_SIZE && cnt_wrap > 0; i++, cnt_wrap--) { + *dst8++ = (uint8_t) (temp & 0xfful); + temp >>= 8; } } - tu_fifo_advance_write_pointer(ff, cnt_lin + cnt_wrap); + // read the rest of the wrapped part + dcd_read_packet_memory(dst8, src, cnt_wrap); + tu_fifo_advance_write_pointer(ff, cnt_total); return true; } diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index 7ebc32255..26717fab0 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -66,10 +66,18 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b // The fsdev_bus_t type can be used for both register and PMA access necessities #ifdef FSDEV_BUS_32BIT typedef uint32_t fsdev_bus_t; + #define fsdevbus_unaligned_read(_addr) tu_unaligned_read32(_addr) + #define fsdevbus_unaligned_write(_addr, _value) tu_unaligned_write32(_addr, _value) #else typedef uint16_t fsdev_bus_t; + #define fsdevbus_unaligned_read(_addr) tu_unaligned_read16(_addr) + #define fsdevbus_unaligned_write(_addr, _value) tu_unaligned_write16(_addr, _value) #endif +enum { + FSDEV_BUS_SIZE = sizeof(fsdev_bus_t), +}; + //--------------------------------------------------------------------+ // BTable Typedef //--------------------------------------------------------------------+ -- cgit v1.3.1 From 0d44977b54c253e6b9faa9b37d56ba7a7522da7a Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 8 Aug 2024 21:38:49 +0700 Subject: add ch32v203 nano to hil pool --- test/hil/hil_test.py | 30 ++++++++++++++++++++++++++++++ test/hil/rpi.json | 7 +++++++ 2 files changed, 37 insertions(+) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index a221982c0..b67520576 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -146,6 +146,36 @@ def flash_openocd(board, firmware): return ret +def flash_openocd_wch(board, firmware): + # Content of the wch-riscv.cfg file + cfg_content = """ +adapter driver wlinke +adapter speed 6000 +transport select sdi + +wlink_set_address 0x00000000 +set _CHIPNAME wch_riscv +sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 + +set _TARGETNAME $_CHIPNAME.cpu + +target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME +$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1 +set _FLASHNAME $_CHIPNAME.flash + +flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 + +echo "Ready for Remote Connections" +""" + f_wch = f"wch-riscv_{board['uid']}.cfg" + if not os.path.exists(f_wch): + with open(f_wch, 'w') as file: + file.write(cfg_content) + + ret = run_cmd(f'openocd_wch -c "adapter serial {board["flasher_sn"]}" -f {f_wch} -c "program {firmware}.elf reset exit"') + return ret + + def flash_wlink_rs(board, firmware): # wlink use index for probe selection and lacking usb serial support ret = run_cmd(f'wlink flash {firmware}.elf') diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 9520f30e2..fd00913f3 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -57,6 +57,13 @@ "flasher": "openocd", "flasher_sn": "066FFF495087534867063844", "flasher_args": "-f interface/stlink.cfg -f target/stm32g0x.cfg" + }, + { + "name": "nanoch32v203", + "uid": "CDAB277B0FBC03E339E339E3", + "flasher": "openocd_wch", + "flasher_sn": "EBCA8F0670AF", + "flasher_args": "" } ], "boards-skip": [ -- cgit v1.3.1 From c3f3465a40b2a83fc7e41e56d5456bceda5ad7a3 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 8 Aug 2024 22:04:54 +0700 Subject: remove hiL build-esp, add riscv support --- .github/workflows/hil_test.yml | 58 +++++------------------------------------- 1 file changed, 6 insertions(+), 52 deletions(-) diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index a4573faf7..d02f13e05 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -44,11 +44,16 @@ jobs: echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT - - name: Setup Toolchain + - name: Setup arm-gcc toolchain uses: ./.github/actions/setup_toolchain with: toolchain: 'arm-gcc' + - name: Setup risv-gcc toolchain + uses: ./.github/actions/setup_toolchain + with: + toolchain: 'riscv-gcc' + - name: Get Dependencies uses: ./.github/actions/get_deps with: @@ -65,56 +70,6 @@ jobs: cmake-build/cmake-build-*/*/*/*.elf cmake-build/cmake-build-*/*/*/*.bin - # --------------------------------------- - # Build Espressif (skipped since CP210x cause USB bus issue) - # cp210x ttyUSB0: usb_serial_generic_write_bulk_callback - nonzero urb status: -71 - # --------------------------------------- - build-esp: - if: false - runs-on: ubuntu-latest - outputs: - BOARDS_LIST: ${{ steps.parse_hil_json.outputs.BOARDS_LIST }} - steps: - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Parse HIL json - id: parse_hil_json - run: | - sudo apt install -y jq - # Espressif boards - BOARDS_LIST=$(jq -r '.boards[] | select(.flasher == "esptool") | "-b " + .name' ${{ env.HIL_JSON }} | tr '\n' ' ') - echo "BOARDS_LIST=$BOARDS_LIST" - echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV - echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT - - - name: Setup ESP-IDF - if: env.BOARDS_LIST != '' - uses: ./.github/actions/setup_toolchain - with: - toolchain: 'esp-idf' - toolchain_url: 'v5.1.1' - - - name: Get Dependencies - uses: ./.github/actions/get_deps - with: - arg: ${{ env.BOARDS_LIST }} - - - name: Build Espressif - if: env.BOARDS_LIST != '' - run: docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python3 tools/build.py $BOARDS_LIST - - - name: Upload Artifacts for Hardware Testing - uses: actions/upload-artifact@v4 - with: - name: hil_rpi_esp - path: | - cmake-build/cmake-build-*/*/*/*.bin - cmake-build/cmake-build-*/*/*/bootloader/bootloader.bin - cmake-build/cmake-build-*/*/*/partition_table/partition-table.bin - cmake-build/cmake-build-*/*/*/config.env - cmake-build/cmake-build-*/*/*/flash_args - # --------------------------------------- # Hardware in the loop (HIL) # self-hosted running on an RPI. For attached hardware checkout test/hil/rpi.json @@ -123,7 +78,6 @@ jobs: if: github.repository_owner == 'hathach' needs: - build - #- build-esp runs-on: [self-hosted, ARM64, rpi, hardware-in-the-loop] env: BOARDS_LIST: "${{ needs.build-esp.outputs.BOARDS_LIST }} ${{ needs.build.outputs.BOARDS_LIST }}" -- cgit v1.3.1 From e7e6fe7cd546c389cdafd1cab9dbf4d60791e70f Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 8 Aug 2024 22:28:13 +0700 Subject: add riscv url --- .github/workflows/hil_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index d02f13e05..1ab50e009 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -53,6 +53,7 @@ jobs: uses: ./.github/actions/setup_toolchain with: toolchain: 'riscv-gcc' + toolchain_url: 'https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz' - name: Get Dependencies uses: ./.github/actions/get_deps -- cgit v1.3.1 From 00eb0144cbb11d1c37dcce5cd8ba8afe10e1b6b5 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 8 Aug 2024 12:55:30 -0700 Subject: Fix ESPs without device support The newer tusb_option.h assumes that there is a number of device endpoints to check against. --- src/common/tusb_mcu.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 637281bfc..e3ad0f627 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -336,8 +336,11 @@ #define TUP_USBIP_DWC2 #define TUP_DCD_ENDPOINT_MAX 6 -#elif TU_CHECK_MCU(OPT_MCU_ESP32, OPT_MCU_ESP32C2, OPT_MCU_ESP32C3, OPT_MCU_ESP32C6, OPT_MCU_ESP32H2) && (CFG_TUD_ENABLED || !(defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)) +#elif TU_CHECK_MCU(OPT_MCU_ESP32, OPT_MCU_ESP32C2, OPT_MCU_ESP32C3, OPT_MCU_ESP32C6, OPT_MCU_ESP32H2) + #if (CFG_TUD_ENABLED || !(defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)) #error "MCUs are only supported with CFG_TUH_MAX3421 enabled" + #endif + #define TUP_DCD_ENDPOINT_MAX 0 //--------------------------------------------------------------------+ // Dialog -- cgit v1.3.1 From ea64dd4999618ce14aea90118ee9218b4aefeba6 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 9 Aug 2024 22:45:35 +0700 Subject: Update ci toolchain (#2758) * move toolchain url to its setup action --- .github/actions/setup_toolchain/action.yml | 29 +++++++++++++++++++--- .../actions/setup_toolchain/espressif/action.yml | 8 +++--- .github/workflows/build.yml | 4 +-- .github/workflows/build_util.yml | 6 ++--- .github/workflows/ci_set_matrix.py | 22 ++++++++-------- .github/workflows/hil_test.yml | 1 - 6 files changed, 44 insertions(+), 26 deletions(-) diff --git a/.github/actions/setup_toolchain/action.yml b/.github/actions/setup_toolchain/action.yml index 19fe28b0c..d173d6903 100644 --- a/.github/actions/setup_toolchain/action.yml +++ b/.github/actions/setup_toolchain/action.yml @@ -4,8 +4,8 @@ inputs: toolchain: description: 'Toolchain name' required: true - toolchain_url: - description: 'Toolchain URL or version' + toolchain_version: + description: 'Toolchain version' required: false outputs: @@ -27,7 +27,28 @@ runs: uses: ./.github/actions/setup_toolchain/espressif with: toolchain: ${{ inputs.toolchain }} - toolchain_url: ${{ inputs.toolchain_url }} + toolchain_version: ${{ inputs.toolchain_version }} + + - name: Get Toolchain URL + if: >- + inputs.toolchain != 'arm-gcc' && + inputs.toolchain != 'arm-iar' && + inputs.toolchain != 'esp-idf' + id: set-toolchain-url + run: | + TOOLCHAIN_JSON='{ + "aarch64-gcc": "https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz", + "arm-clang": "https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-17.0.1/LLVMEmbeddedToolchainForArm-17.0.1-Linux-x86_64.tar.xz", + "arm-iar": "", + "arm-gcc": "", + "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", + "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz", + "rx-gcc": "http://gcc-renesas.com/downloads/get.php?f=rx/8.3.0.202004-gnurx/gcc-8.3.0.202004-GNURX-ELF.run" + }' + TOOLCHAIN_URL=$(echo $TOOLCHAIN_JSON | jq -r '.["${{ inputs.toolchain }}"]') + echo "toolchain_url=$TOOLCHAIN_URL" + echo "toolchain_url=$TOOLCHAIN_URL" >> $GITHUB_OUTPUT + shell: bash - name: Download Toolchain if: >- @@ -37,7 +58,7 @@ runs: uses: ./.github/actions/setup_toolchain/download with: toolchain: ${{ inputs.toolchain }} - toolchain_url: ${{ inputs.toolchain_url }} + toolchain_url: ${{ steps.set-toolchain-url.outputs.toolchain_url }} - name: Set toolchain option id: set-toolchain-option diff --git a/.github/actions/setup_toolchain/espressif/action.yml b/.github/actions/setup_toolchain/espressif/action.yml index 46da02911..3129329dd 100644 --- a/.github/actions/setup_toolchain/espressif/action.yml +++ b/.github/actions/setup_toolchain/espressif/action.yml @@ -4,7 +4,7 @@ inputs: toolchain: description: 'Toolchain name' required: true - toolchain_url: + toolchain_version: description: 'Toolchain URL or version' required: true @@ -22,14 +22,14 @@ runs: id: cache-toolchain-espressif with: path: ${{ env.DOCKER_ESP_IDF }} - key: ${{ inputs.toolchain }}-${{ inputs.toolchain_url }} + key: ${{ inputs.toolchain }}-${{ inputs.toolchain_version }} - name: Pull and Save Docker Image if: steps.cache-toolchain-espressif.outputs.cache-hit != 'true' run: | - docker pull espressif/idf:${{ inputs.toolchain_url }} + docker pull espressif/idf:${{ inputs.toolchain_version }} mkdir -p $(dirname $DOCKER_ESP_IDF) - docker save -o $DOCKER_ESP_IDF espressif/idf:${{ inputs.toolchain_url }} + docker save -o $DOCKER_ESP_IDF espressif/idf:${{ inputs.toolchain_version }} du -sh $DOCKER_ESP_IDF shell: bash diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fda7f0294..b3dc3ec42 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,7 +66,6 @@ jobs: with: build-system: 'cmake' toolchain: ${{ matrix.toolchain }} - toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} one-per-family: ${{ github.event_name != 'pull_request' }} @@ -90,7 +89,6 @@ jobs: with: build-system: 'make' toolchain: ${{ matrix.toolchain }} - toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} one-per-family: ${{ github.event_name != 'pull_request' }} @@ -125,7 +123,7 @@ jobs: with: build-system: 'cmake' toolchain: 'esp-idf' - toolchain_url: 'v5.1.1' + toolchain_version: 'v5.1.1' build-args: '["-b${{ matrix.board }}"]' # --------------------------------------- diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 49a9feabd..b0a87d4df 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -9,7 +9,7 @@ on: toolchain: required: true type: string - toolchain_url: + toolchain_version: required: false type: string build-args: @@ -40,7 +40,7 @@ jobs: uses: ./.github/actions/setup_toolchain with: toolchain: ${{ inputs.toolchain }} - toolchain_url: ${{ inputs.toolchain_url }} + toolchain_version: ${{ inputs.toolchain_version }} - name: Get Dependencies uses: ./.github/actions/get_deps @@ -65,4 +65,4 @@ jobs: - name: Build using ESP-IDF docker if: inputs.toolchain == 'esp-idf' run: | - docker run --rm -v $PWD:/project -w /project espressif/idf:${{ inputs.toolchain_url }} python3 tools/build.py ${{ matrix.arg }} + docker run --rm -v $PWD:/project -w /project espressif/idf:${{ inputs.toolchain_version }} python3 tools/build.py ${{ matrix.arg }} diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 2a00e5413..a56bd4214 100644 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -1,15 +1,15 @@ import json # toolchain, url -toolchain_list = { - "aarch64-gcc": "https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz", - "arm-clang": "https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-17.0.1/LLVMEmbeddedToolchainForArm-17.0.1-Linux-x86_64.tar.xz", - "arm-iar": "", - "arm-gcc": "", - "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", - "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz", - "rx-gcc": "http://gcc-renesas.com/downloads/get.php?f=rx/8.3.0.202004-gnurx/gcc-8.3.0.202004-GNURX-ELF.run", -} +toolchain_list = [ + "aarch64-gcc", + "arm-clang", + "arm-iar", + "arm-gcc", + "msp430-gcc", + "riscv-gcc", + "rx-gcc" +] # family: [supported toolchain] family_list = { @@ -44,7 +44,7 @@ family_list = { def set_matrix_json(): matrix = {} - for toolchain in toolchain_list.keys(): + for toolchain in toolchain_list: filtered_families = [family for family, supported_toolchain in family_list.items() if toolchain in supported_toolchain] @@ -55,7 +55,7 @@ def set_matrix_json(): hfp_boards = [f"-b{board['name']}" for board in hfp_data['boards']] filtered_families = filtered_families + hfp_boards - matrix[toolchain] = {"family": filtered_families, "toolchain_url": toolchain_list[toolchain]} + matrix[toolchain] = {"family": filtered_families} print(json.dumps(matrix)) diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index 1ab50e009..d02f13e05 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -53,7 +53,6 @@ jobs: uses: ./.github/actions/setup_toolchain with: toolchain: 'riscv-gcc' - toolchain_url: 'https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz' - name: Get Dependencies uses: ./.github/actions/get_deps -- cgit v1.3.1 From b786d6f4e632654a356932115bfc0c1621f6333b Mon Sep 17 00:00:00 2001 From: Hjalmar Date: Fri, 9 Aug 2024 21:08:32 +0200 Subject: Marked the keycode parameter of the keyboard_report functions as const since the functions don't modifies the value --- src/class/hid/hid_device.c | 2 +- src/class/hid/hid_device.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 00f6fc474..ef6c7f3af 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -134,7 +134,7 @@ uint8_t tud_hid_n_get_protocol(uint8_t instance) { return _hidd_itf[instance].protocol_mode; } -bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) { +bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, const uint8_t keycode[6]) { hid_keyboard_report_t report; report.modifier = modifier; report.reserved = 0; diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 89c28e061..ab2e27373 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -65,7 +65,7 @@ bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, u // KEYBOARD: convenient helper to send keyboard report if application // use template layout report as defined by hid_keyboard_report_t -bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]); +bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, const uint8_t keycode[6]); // MOUSE: convenient helper to send mouse report if application // use template layout report as defined by hid_mouse_report_t @@ -98,7 +98,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_report(uint8_t report_id, void return tud_hid_n_report(0, report_id, report, len); } -TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) { +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, const uint8_t keycode[6]) { return tud_hid_n_keyboard_report(0, report_id, modifier, keycode); } -- cgit v1.3.1 From e8f42df97a4421d90a4565f22308c5adb9560cf5 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 10 Aug 2024 09:47:34 +0700 Subject: change pio to fix rp2040 build --- tools/get_deps.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/get_deps.py b/tools/get_deps.py index 7fbde0e02..c7cf6ca63 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -54,8 +54,8 @@ deps_optional = { 'hw/mcu/nxp/mcux-sdk': ['https://github.com/hathach/mcux-sdk.git', '144f1eb7ea8c06512e12f12b27383601c0272410', 'kinetis_k kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx imxrt'], - 'hw/mcu/raspberry_pi/Pico-PIO-USB': ['https://github.com/sekigon-gonnoc/Pico-PIO-USB.git', - '0f747aaa0c16f750bdfa2ba37ec25d6c8e1bc117', + 'hw/mcu/raspberry_pi/Pico-PIO-USB': ['https://github.com/adafruit/Pico-PIO-USB.git', + '770e3b2e4af14dd202f062f850f9f14820ecbb1e', 'rp2040'], 'hw/mcu/renesas/fsp': ['https://github.com/renesas/fsp.git', 'd52e5a6a59b7c638da860c2bb309b6e78e752ff8', -- cgit v1.3.1 From c07928e1b3bb680cb55de3a55eae9ba3cb459694 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 10 Aug 2024 22:07:10 +0700 Subject: fix build with rp2040 PICO_DEFAULT_SPI rename --- hw/bsp/rp2040/board.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hw/bsp/rp2040/board.h b/hw/bsp/rp2040/board.h index 3849894ce..733e93797 100644 --- a/hw/bsp/rp2040/board.h +++ b/hw/bsp/rp2040/board.h @@ -78,7 +78,12 @@ // USB Host MAX3421E //-------------------------------------------------------------------- -#define MAX3421_SPI PICO_DEFAULT_SPI_INSTANCE +#ifdef PICO_DEFAULT_SPI +#define MAX3421_SPI PICO_DEFAULT_SPI // sdk v2 +#else +#define MAX3421_SPI PICO_DEFAULT_SPI_INSTANCE // sdk v1 +#endif + #define MAX3421_SCK_PIN PICO_DEFAULT_SPI_SCK_PIN #define MAX3421_MOSI_PIN PICO_DEFAULT_SPI_TX_PIN #define MAX3421_MISO_PIN PICO_DEFAULT_SPI_RX_PIN -- cgit v1.3.1 From 2871bb0da6c928f6593f7eaa7cd4e1c4c287db43 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 11 Aug 2024 00:51:51 +0700 Subject: fix spi_set_format() -Wnull-dereference when compiling with -Os --- .github/workflows/build_util.yml | 13 ++++++------- hw/bsp/rp2040/family.c | 8 ++++++++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index b0a87d4df..e983f06d1 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -58,11 +58,10 @@ jobs: shell: bash - name: Build - if: inputs.toolchain != 'esp-idf' run: | - python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} - - - name: Build using ESP-IDF docker - if: inputs.toolchain == 'esp-idf' - run: | - docker run --rm -v $PWD:/project -w /project espressif/idf:${{ inputs.toolchain_version }} python3 tools/build.py ${{ matrix.arg }} + if [ "${{ inputs.toolchain }}" == "esp-idf" ]; then + docker run --rm -v $PWD:/project -w /project espressif/idf:${{ inputs.toolchain_version }} python3 tools/build.py ${{ matrix.arg }} + else + python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} + fi + shell: bash diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index 9360f7f57..250989ce9 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -275,7 +275,15 @@ static void max3421_init(void) { gpio_set_function(MAX3421_SCK_PIN, GPIO_FUNC_SPI); gpio_set_function(MAX3421_MOSI_PIN, GPIO_FUNC_SPI); gpio_set_function(MAX3421_MISO_PIN, GPIO_FUNC_SPI); + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnull-dereference" +#endif spi_set_format(MAX3421_SPI, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST); +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif } //// API to enable/disable MAX3421 INTR pin interrupt -- cgit v1.3.1 From 8b88749223e969148e9d1ce4c8fd3a6756d5e38c Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 11 Aug 2024 09:51:14 +0700 Subject: skip ch32v203 for hil test --- test/hil/rpi.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/hil/rpi.json b/test/hil/rpi.json index fd00913f3..396b21553 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -57,16 +57,16 @@ "flasher": "openocd", "flasher_sn": "066FFF495087534867063844", "flasher_args": "-f interface/stlink.cfg -f target/stm32g0x.cfg" - }, + } + ], + "boards-skip": [ { "name": "nanoch32v203", "uid": "CDAB277B0FBC03E339E339E3", "flasher": "openocd_wch", "flasher_sn": "EBCA8F0670AF", "flasher_args": "" - } - ], - "boards-skip": [ + }, { "name": "espressif_s3_devkitm", "uid": "84F703C084E4", -- cgit v1.3.1 From 7a9ef9e7bdbd915e96ed40dbe76111959a92ce9f Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 11 Aug 2024 11:10:15 +0700 Subject: readd v203 to hil pool --- test/hil/rpi.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 396b21553..fd00913f3 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -57,16 +57,16 @@ "flasher": "openocd", "flasher_sn": "066FFF495087534867063844", "flasher_args": "-f interface/stlink.cfg -f target/stm32g0x.cfg" - } - ], - "boards-skip": [ + }, { "name": "nanoch32v203", "uid": "CDAB277B0FBC03E339E339E3", "flasher": "openocd_wch", "flasher_sn": "EBCA8F0670AF", "flasher_args": "" - }, + } + ], + "boards-skip": [ { "name": "espressif_s3_devkitm", "uid": "84F703C084E4", -- cgit v1.3.1 From a621c4b6fcd89df9b86d2911414e05e2e15184ec Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 12 Aug 2024 16:39:25 +0700 Subject: fix more race with ch32v203 and setup when queuing zlp. improve hil test failed output --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 22 ++++--- src/portable/st/stm32_fsdev/fsdev_type.h | 5 +- test/hil/hil_test.py | 93 ++++++++++++++++----------- 3 files changed, 73 insertions(+), 47 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 252969648..1e0e9c447 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -345,12 +345,14 @@ static void handle_ctr_rx(uint32_t ep_id) { if ((rx_count < xfer->max_packet_size) || (xfer->queued_len >= xfer->total_len)) { // all bytes received or short packet - dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); // For ch32v203: reset rx bufsize to mps to prevent race condition to cause PMAOVR (occurs with msc write10) - // also ch32 seems to unconditionally accept ZLP on EP0 OUT, which can incorrectly use queued_len of previous - // transfer. So reset total_len and queued_len to 0. btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, xfer->max_packet_size); + + dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); + + // ch32 seems to unconditionally accept ZLP on EP0 OUT, which can incorrectly use queued_len of previous + // transfer. So reset total_len and queued_len to 0. xfer->total_len = xfer->queued_len = 0; } else { // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always @@ -412,11 +414,6 @@ void dcd_int_handler(uint8_t rhport) { FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF; } - if (int_status & USB_ISTR_PMAOVR) { - TU_BREAKPOINT(); - FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_PMAOVR; - } - // loop to handle all pending CTR interrupts while (FSDEV_REG->ISTR & USB_ISTR_CTR) { // skip DIR bit, and use CTR TX/RX instead, since there is chance we have both TX/RX completed in one interrupt @@ -459,6 +456,11 @@ void dcd_int_handler(uint8_t rhport) { handle_ctr_tx(ep_id); } } + + if (int_status & USB_ISTR_PMAOVR) { + TU_BREAKPOINT(); + FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_PMAOVR; + } } //--------------------------------------------------------------------+ @@ -806,6 +808,10 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { ep_write(ep_idx, ep_reg, true); } +//--------------------------------------------------------------------+ +// PMA read/write +//--------------------------------------------------------------------+ + // Write to packet memory area (PMA) from user memory // - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT // - Uses unaligned for RAM (since M0 cannot access unaligned address) diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index 26717fab0..cf36576bb 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -285,8 +285,9 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10); if (bl_nb == 0) { - // zlp but 0 is invalid value, set num_block to 1 (2 bytes) - bl_nb = 1 << 10; + // zlp but 0 is invalid value, set blsize to 1 (32 bytes) + // Note: lower value can cause PMAOVR on setup with ch32v203 + bl_nb = 1 << 15; } #ifdef FSDEV_BUS_32BIT diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index b67520576..01ca93c7a 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -36,7 +36,7 @@ import glob import platform from multiprocessing import Pool -ENUM_TIMEOUT = 30 +ENUM_TIMEOUT = 20 # get usb serial by id @@ -110,7 +110,8 @@ def run_cmd(cmd): #print(cmd) r = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if r.returncode != 0: - title = 'command error' + title = f'COMMAND FAILED: {cmd}' + print() if os.getenv('CI'): print(f"::group::{title}") print(r.stdout.decode("utf-8")) @@ -198,14 +199,15 @@ def flash_esptool(board, firmware): # ------------------------------------------------------------- # Tests # ------------------------------------------------------------- -def test_board_test(id): +def test_board_test(board): # Dummy test pass -def test_cdc_dual_ports(id): - port1 = get_serial_dev(id, 'TinyUSB', "TinyUSB_Device", 0) - port2 = get_serial_dev(id, 'TinyUSB', "TinyUSB_Device", 2) +def test_cdc_dual_ports(board): + uid = board['uid'] + port1 = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 0) + port2 = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 2) ser1 = open_serial_dev(port1) ser2 = open_serial_dev(port2) @@ -224,9 +226,10 @@ def test_cdc_dual_ports(id): assert ser2.read(100) == str2.upper(), 'Port2 wrong data' -def test_cdc_msc(id): +def test_cdc_msc(board): + uid = board['uid'] # Echo test - port = get_serial_dev(id, 'TinyUSB', "TinyUSB_Device", 0) + port = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 0) ser = open_serial_dev(port) str = b"test_str" @@ -235,7 +238,7 @@ def test_cdc_msc(id): assert ser.read(100) == str, 'CDC wrong data' # Block test - data = read_disk_file(id, 'README.TXT') + data = read_disk_file(uid, 'README.TXT') readme = \ b"This is tinyusb's MassStorage Class demo.\r\n\r\n\ If you find any bugs or get any questions, feel free to file an\r\n\ @@ -244,26 +247,28 @@ issue at github.com/hathach/tinyusb" assert data == readme, 'MSC wrong data' -def test_cdc_msc_freertos(id): - test_cdc_msc(id) +def test_cdc_msc_freertos(board): + test_cdc_msc(board) -def test_dfu(id): +def test_dfu(board): + uid = board['uid'] + # Wait device enum timeout = ENUM_TIMEOUT while timeout: ret = subprocess.run(f'dfu-util -l', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout = ret.stdout.decode() - if f'serial="{id}"' in stdout and 'Found DFU: [cafe:4000]' in stdout: + if f'serial="{uid}"' in stdout and 'Found DFU: [cafe:4000]' in stdout: break time.sleep(1) timeout = timeout - 1 assert timeout, 'Device not available' - f_dfu0 = f'dfu0_{id}' - f_dfu1 = f'dfu1_{id}' + f_dfu0 = f'dfu0_{uid}' + f_dfu1 = f'dfu1_{uid}' # Test upload try: @@ -272,10 +277,10 @@ def test_dfu(id): except OSError: pass - ret = run_cmd(f'dfu-util -S {id} -a 0 -U {f_dfu0}') + ret = run_cmd(f'dfu-util -S {uid} -a 0 -U {f_dfu0}') assert ret.returncode == 0, 'Upload failed' - ret = run_cmd(f'dfu-util -S {id} -a 1 -U {f_dfu1}') + ret = run_cmd(f'dfu-util -S {uid} -a 1 -U {f_dfu1}') assert ret.returncode == 0, 'Upload failed' with open(f_dfu0) as f: @@ -288,14 +293,16 @@ def test_dfu(id): os.remove(f_dfu1) -def test_dfu_runtime(id): +def test_dfu_runtime(board): + uid = board['uid'] + # Wait device enum timeout = ENUM_TIMEOUT while timeout: ret = subprocess.run(f'dfu-util -l', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout = ret.stdout.decode() - if f'serial="{id}"' in stdout and 'Found Runtime: [cafe:4000]' in stdout: + if f'serial="{uid}"' in stdout and 'Found Runtime: [cafe:4000]' in stdout: break time.sleep(1) timeout = timeout - 1 @@ -303,10 +310,11 @@ def test_dfu_runtime(id): assert timeout, 'Device not available' -def test_hid_boot_interface(id): - kbd = get_hid_dev(id, 'TinyUSB', 'TinyUSB_Device', 'event-kbd') - mouse1 = get_hid_dev(id, 'TinyUSB', 'TinyUSB_Device', 'if01-event-mouse') - mouse2 = get_hid_dev(id, 'TinyUSB', 'TinyUSB_Device', 'if01-mouse') +def test_hid_boot_interface(board): + uid = board['uid'] + kbd = get_hid_dev(uid, 'TinyUSB', 'TinyUSB_Device', 'event-kbd') + mouse1 = get_hid_dev(uid, 'TinyUSB', 'TinyUSB_Device', 'if01-event-mouse') + mouse2 = get_hid_dev(uid, 'TinyUSB', 'TinyUSB_Device', 'if01-mouse') # Wait device enum timeout = ENUM_TIMEOUT while timeout: @@ -338,22 +346,23 @@ all_tests = [ ] -def test_board(item): - name = item['name'] - flasher = item['flasher'].lower() +def test_board(board): + name = board['name'] + flasher = board['flasher'].lower() # default to all tests - if 'tests' in item: - test_list = item['tests'] + ['board_test'] + if 'tests' in board: + test_list = board['tests'] + ['board_test'] else: test_list = list(all_tests) # remove skip_tests - if 'tests_skip' in item: - for skip in item['tests_skip']: + if 'tests_skip' in board: + for skip in board['tests_skip']: if skip in test_list: test_list.remove(skip) + err_count = 0 for test in test_list: fw_dir = f'cmake-build/cmake-build-{name}/device/{test}' if not os.path.exists(fw_dir): @@ -367,19 +376,26 @@ def test_board(item): # flash firmware. It may fail randomly, retry a few times for i in range(3): - ret = globals()[f'flash_{flasher}'](item, fw_name) + ret = globals()[f'flash_{flasher}'](board, fw_name) if ret.returncode == 0: break else: print(f'Flashing failed, retry {i+1}') time.sleep(1) - assert ret.returncode == 0, 'Flash failed\n' + ret.stdout.decode() - - # run test - globals()[f'test_{test}'](item['uid']) - print('OK') + if ret.returncode == 0: + try: + ret = globals()[f'test_{test}'](board) + print('OK') + except AssertionError as e: + err_count += 1 + print('Failed') + print(f' {e}') + else: + err_count += 1 + print('Flash failed') + return err_count def main(): """ @@ -404,8 +420,11 @@ def main(): else: config_boards = [e for e in config['boards'] if e['name'] in boards] + err_count_list = 0 with Pool(processes=os.cpu_count()) as pool: - pool.map(test_board, config_boards) + err_count_list = pool.map(test_board, config_boards) + + sys.exit(sum(err_count_list)) if __name__ == '__main__': -- cgit v1.3.1 From 5666aa196f99e323e025179559ef8ac1db390749 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 12 Aug 2024 15:38:22 +0200 Subject: Fix tusb_dir_t warning. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 1e0e9c447..ed9036d19 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -155,7 +155,7 @@ static uint8_t remoteWakeCountdown; // When wake is requested // into the stack. static void handle_bus_reset(uint8_t rhport); static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix); -static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir); +static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir); // PMA allocation/access static uint16_t ep_buf_ptr; ///< Points to first free memory location @@ -578,7 +578,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void)rhport; uint8_t const ep_addr = desc_ep->bEndpointAddress; uint8_t const ep_num = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); const uint16_t packet_size = tu_edpt_packet_size(desc_ep); uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); TU_ASSERT(ep_idx < FSDEV_EP_COUNT); @@ -671,7 +671,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) (void)rhport; uint8_t const ep_addr = desc_ep->bEndpointAddress; uint8_t const ep_num = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir); uint8_t const ep_idx = xfer->ep_idx; @@ -683,7 +683,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); ep_change_dtog(&ep_reg, dir, 0); - ep_change_dtog(&ep_reg, 1 - dir, 1); + ep_change_dtog(&ep_reg, (tusb_dir_t)(1 - dir), 1); ep_write(ep_idx, ep_reg, true); @@ -722,7 +722,7 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { ep_write(ep_ix, ep_reg, true); } -static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { +static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir) { (void) rhport; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); @@ -752,7 +752,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { uint8_t const ep_num = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); xfer->buffer = buffer; @@ -765,7 +765,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) { uint8_t const ep_num = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); xfer->buffer = NULL; @@ -779,7 +779,7 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; uint8_t const ep_num = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); uint8_t const ep_idx = xfer->ep_idx; @@ -794,7 +794,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; uint8_t const ep_num = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); uint8_t const ep_idx = xfer->ep_idx; -- cgit v1.3.1 From 549f20d1793d1896a376a1ea978a4f02217de4ed Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 12 Aug 2024 15:39:02 +0200 Subject: Fix buf_id read for ISO transfer. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index ed9036d19..0cdc3eef9 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -275,7 +275,6 @@ static void handle_bus_reset(uint8_t rhport) { // Handle CTR interrupt for the TX/IN direction static void handle_ctr_tx(uint32_t ep_id) { uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX; - ep_reg &= USB_EPREG_MASK; uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_IN); @@ -694,7 +693,6 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR - ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); // only change TX Status, reserve other toggle bits bool const is_iso = ep_is_iso(ep_reg); @@ -719,6 +717,7 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { if (is_iso) { xfer->iso_in_sending = true; } + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); // only change TX Status, reserve other toggle bits ep_write(ep_ix, ep_reg, true); } -- cgit v1.3.1 From f565267dafe63a8f92e53ba5e511f07ea34eaaa4 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 12 Aug 2024 18:32:51 +0200 Subject: Fix stm32l0 clock init. --- hw/bsp/stm32l0/boards/stm32l052dap52/board.h | 9 +++++---- hw/bsp/stm32l0/boards/stm32l0538disco/board.h | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/hw/bsp/stm32l0/boards/stm32l052dap52/board.h b/hw/bsp/stm32l0/boards/stm32l052dap52/board.h index c8963199b..ee83bbcbc 100644 --- a/hw/bsp/stm32l0/boards/stm32l052dap52/board.h +++ b/hw/bsp/stm32l0/boards/stm32l052dap52/board.h @@ -54,16 +54,17 @@ //--------------------------------------------------------------------+ static inline void board_stm32l0_clock_init(void) { - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; - static RCC_CRSInitTypeDef RCC_CRSInitStruct; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + RCC_CRSInitTypeDef RCC_CRSInitStruct = {0}; /* Enable HSI Oscillator to be used as System clock source Enable HSI48 Oscillator to be used as USB clock source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select HSI48 as USB clock source */ diff --git a/hw/bsp/stm32l0/boards/stm32l0538disco/board.h b/hw/bsp/stm32l0/boards/stm32l0538disco/board.h index 0722e3102..5cda1c15a 100644 --- a/hw/bsp/stm32l0/boards/stm32l0538disco/board.h +++ b/hw/bsp/stm32l0/boards/stm32l0538disco/board.h @@ -54,16 +54,17 @@ //--------------------------------------------------------------------+ static inline void board_stm32l0_clock_init(void) { - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; - static RCC_CRSInitTypeDef RCC_CRSInitStruct; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + RCC_CRSInitTypeDef RCC_CRSInitStruct = {0}; /* Enable HSI Oscillator to be used as System clock source Enable HSI48 Oscillator to be used as USB clock source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select HSI48 as USB clock source */ -- cgit v1.3.1 From 96c5c72e971674ba3a4023aed02bf31cc8c994dc Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 12 Aug 2024 18:38:23 +0200 Subject: Fix double buffer not disabled for smaller devices. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 0cdc3eef9..6eea1ab32 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -650,10 +650,11 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet /* Create a packet memory buffer area. Enable double buffering for devices with 2048 bytes PMA, for smaller devices double buffering occupy too much space. */ - uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, true); #if FSDEV_PMA_SIZE > 1024u + uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, true); uint16_t pma_addr2 = pma_addr >> 16; #else + uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, false); uint16_t pma_addr2 = pma_addr; #endif -- cgit v1.3.1 From ad411b6c252265676d9a61f77fd8a5c26465b392 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 13 Aug 2024 10:55:17 +0700 Subject: minor update to cmake profile --- .idea/cmake.xml | 114 +++++++++++----------- hw/bsp/stm32f1/boards/stm32f103ze_iar/board.cmake | 1 + hw/bsp/stm32l0/boards/stm32l0538disco/board.cmake | 1 + 3 files changed, 59 insertions(+), 57 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index bf5696725..729309ebb 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -4,140 +4,140 @@ - - - - + + + + - + - + - + - + - + - + - + - - - + + + - + - - - - - - - - - - - + + + + + + + + + + + - - - - - + + + + + - + - + - - + + - + - - + + - - + + - - - - - + + + + + - + - - - + + + - - - - - + + + + + - + - + - + diff --git a/hw/bsp/stm32f1/boards/stm32f103ze_iar/board.cmake b/hw/bsp/stm32f1/boards/stm32f103ze_iar/board.cmake index c797d7090..7672ff338 100644 --- a/hw/bsp/stm32f1/boards/stm32f103ze_iar/board.cmake +++ b/hw/bsp/stm32f1/boards/stm32f103ze_iar/board.cmake @@ -1,5 +1,6 @@ set(MCU_VARIANT stm32f103xe) set(JLINK_DEVICE stm32f103ze) +#set(JLINK_OPTION "-USB 320000338") string(TOUPPER ${MCU_VARIANT} MCU_VARIANT_UPPER) diff --git a/hw/bsp/stm32l0/boards/stm32l0538disco/board.cmake b/hw/bsp/stm32l0/boards/stm32l0538disco/board.cmake index 8d7b537d5..895bbb3ab 100644 --- a/hw/bsp/stm32l0/boards/stm32l0538disco/board.cmake +++ b/hw/bsp/stm32l0/boards/stm32l0538disco/board.cmake @@ -1,5 +1,6 @@ set(MCU_VARIANT stm32l053xx) set(JLINK_DEVICE stm32l053r8) +#set(JLINK_OPTION "-USB 778921770") set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32L053C8Tx_FLASH.ld) -- cgit v1.3.1 From 45f50ebaa8dd4d2542d2db8fe51783803c8698be Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 13 Aug 2024 11:04:53 +0700 Subject: increase enum timeout --- test/hil/hil_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 01ca93c7a..597d6c5ca 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -36,7 +36,7 @@ import glob import platform from multiprocessing import Pool -ENUM_TIMEOUT = 20 +ENUM_TIMEOUT = 30 # get usb serial by id -- cgit v1.3.1 From 61725a5263b6820051d515fcb716e4a91c13cdac Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 13 Aug 2024 13:16:46 +0700 Subject: fix concurrent mass storage test conflict, use pyfatfs to access disk dev by usb id instead of mounted in /media/ --- test/hil/hil_test.py | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 597d6c5ca..9a7fe8321 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -33,8 +33,8 @@ import serial import subprocess import json import glob -import platform from multiprocessing import Pool +import fs ENUM_TIMEOUT = 30 @@ -53,9 +53,8 @@ def get_serial_dev(id, vendor_str, product_str, ifnum): return port_list[0] -# Currently not used, left as reference +# get usb disk by id def get_disk_dev(id, vendor_str, lun): - # get usb disk by id return f'/dev/disk/by-id/usb-{vendor_str}_Mass_Storage_{id}-0:{lun}' @@ -72,34 +71,34 @@ def open_serial_dev(port): # slight delay since kernel may occupy the port briefly time.sleep(0.5) timeout = timeout - 0.5 - ser = serial.Serial(port, timeout=1) + ser = serial.Serial(port, timeout=2) break except serial.SerialException: pass time.sleep(0.5) timeout = timeout - 0.5 - assert timeout, 'Device not available or Cannot open port' + + assert timeout, f'Cannot open port f{port}' if os.path.exists(port) else f'Port {port} not existed' return ser -def read_disk_file(id, fname): - # on different self-hosted, the mount point is different - file_list = [ - f'/media/blkUSB_{id[-8:]}.02/{fname}', - f'/media/{os.getenv("USER")}/TinyUSB MSC/{fname}' - ] +def read_disk_file(uid, lun, fname): + # open_fs("fat://{dev}) require 'pip install pyfatfs' + dev = get_disk_dev(uid, 'TinyUSB', lun) timeout = ENUM_TIMEOUT while timeout: - for file in file_list: - if os.path.isfile(file): - with open(file, 'rb') as f: - data = f.read() - return data - + if os.path.exists(dev): + fat = fs.open_fs(f'fat://{dev}') + try: + assert fat.exists(fname), f'File {fname} not found in {dev}' + with fat.open(fname, 'rb') as f: + return f.read() + finally: + fat.close() time.sleep(1) timeout = timeout - 1 - assert timeout, 'Device not available' + assert timeout, f'Storage {dev} not existed' return None @@ -238,7 +237,7 @@ def test_cdc_msc(board): assert ser.read(100) == str, 'CDC wrong data' # Block test - data = read_disk_file(uid, 'README.TXT') + data = read_disk_file(uid,0,'README.TXT') readme = \ b"This is tinyusb's MassStorage Class demo.\r\n\r\n\ If you find any bugs or get any questions, feel free to file an\r\n\ @@ -397,6 +396,7 @@ def test_board(board): return err_count + def main(): """ Hardware test on specified boards -- cgit v1.3.1 From f23170786abe8bde0a00065987674f6ff66104c5 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 13 Aug 2024 13:50:19 +0700 Subject: increase pyserial timeout --- test/hil/hil_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 9a7fe8321..ff8034b95 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -71,7 +71,7 @@ def open_serial_dev(port): # slight delay since kernel may occupy the port briefly time.sleep(0.5) timeout = timeout - 0.5 - ser = serial.Serial(port, timeout=2) + ser = serial.Serial(port, timeout=5) break except serial.SerialException: pass -- cgit v1.3.1 From 525406597627fb9307425539b86dddf10278eca8 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 13 Aug 2024 13:51:28 +0700 Subject: change pio-usb back to upstreaam --- tools/get_deps.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/get_deps.py b/tools/get_deps.py index c7cf6ca63..b639ed6d6 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -54,8 +54,8 @@ deps_optional = { 'hw/mcu/nxp/mcux-sdk': ['https://github.com/hathach/mcux-sdk.git', '144f1eb7ea8c06512e12f12b27383601c0272410', 'kinetis_k kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx imxrt'], - 'hw/mcu/raspberry_pi/Pico-PIO-USB': ['https://github.com/adafruit/Pico-PIO-USB.git', - '770e3b2e4af14dd202f062f850f9f14820ecbb1e', + 'hw/mcu/raspberry_pi/Pico-PIO-USB': ['https://github.com/sekigon-gonnoc/Pico-PIO-USB.git', + '7902e9fa8ed4a271d8d1d5e7e50516c2292b7bc2', 'rp2040'], 'hw/mcu/renesas/fsp': ['https://github.com/renesas/fsp.git', 'd52e5a6a59b7c638da860c2bb309b6e78e752ff8', -- cgit v1.3.1 From 5f8599f6d44c1b1741f3e0edf0d342720c0c17d8 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 13 Aug 2024 14:35:42 +0700 Subject: metro m7 has issue with cdc_msc example randomly on hil test. Exclude it for now --- test/hil/hil_test.py | 11 ++++++----- test/hil/rpi.json | 2 ++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index ff8034b95..c6feb7de2 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -88,15 +88,16 @@ def read_disk_file(uid, lun, fname): timeout = ENUM_TIMEOUT while timeout: if os.path.exists(dev): - fat = fs.open_fs(f'fat://{dev}') + fat = fs.open_fs(f'fat://{dev}?read_only=true') try: - assert fat.exists(fname), f'File {fname} not found in {dev}' with fat.open(fname, 'rb') as f: - return f.read() + data = f.read() finally: fat.close() + assert data, f'Cannot read file {fname} from {dev}' + return data time.sleep(1) - timeout = timeout - 1 + timeout -= 1 assert timeout, f'Storage {dev} not existed' return None @@ -322,7 +323,7 @@ def test_hid_boot_interface(board): time.sleep(1) timeout = timeout - 1 - assert timeout, 'Device not available' + assert timeout, 'HID device not available' def test_hid_composite_freertos(id): diff --git a/test/hil/rpi.json b/test/hil/rpi.json index fd00913f3..a4f6073eb 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -17,6 +17,8 @@ { "name": "metro_m7_1011", "uid": "9CE8715DD71137363E00005002004200", + "tests_skip": ["cdc_msc", "cdc_msc_freertos"], + "comment": "Somehow has issue with cdc_msc example randomly", "flasher": "jlink", "flasher_sn": "000611000000", "flasher_args": "-device MIMXRT1011xxx5A" -- cgit v1.3.1 From 0f732a2f8b83ba5a6eebacf4ded73a682214591e Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 13 Aug 2024 14:50:54 +0700 Subject: remove metro m7 for now --- test/hil/hil_test.py | 2 +- test/hil/rpi.json | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index c6feb7de2..c2ed4d94e 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -387,7 +387,7 @@ def test_board(board): try: ret = globals()[f'test_{test}'](board) print('OK') - except AssertionError as e: + except Exception as e: err_count += 1 print('Failed') print(f' {e}') diff --git a/test/hil/rpi.json b/test/hil/rpi.json index a4f6073eb..5f218d073 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -14,15 +14,6 @@ "flasher_sn": "E6614C311B597D32", "flasher_args": "-f interface/cmsis-dap.cfg -f target/atsame5x.cfg -c \"adapter speed 5000\"" }, - { - "name": "metro_m7_1011", - "uid": "9CE8715DD71137363E00005002004200", - "tests_skip": ["cdc_msc", "cdc_msc_freertos"], - "comment": "Somehow has issue with cdc_msc example randomly", - "flasher": "jlink", - "flasher_sn": "000611000000", - "flasher_args": "-device MIMXRT1011xxx5A" - }, { "name": "lpcxpresso11u37", "uid": "17121919", @@ -69,6 +60,14 @@ } ], "boards-skip": [ + { + "name": "metro_m7_1011", + "uid": "9CE8715DD71137363E00005002004200", + "flasher": "jlink", + "flasher_sn": "000611000000", + "flasher_args": "-device MIMXRT1011xxx5A", + "comment": "sometime it is not enumerated/not reset, maybe need an bsp explicit disconnect/reconnect" + }, { "name": "espressif_s3_devkitm", "uid": "84F703C084E4", -- cgit v1.3.1 From 86419df42c3220a867a3ffbc22140e11b7ad57ee Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 13 Aug 2024 16:01:51 +0700 Subject: use zero wait flash for nano v203 --- hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake | 4 ++-- test/hil/hil_test.py | 2 +- test/hil/rpi.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake index a0bf12b5c..6c7712cdd 100644 --- a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake @@ -1,8 +1,8 @@ set(MCU_VARIANT D6) # 64KB zero-wait, 224KB total flash -#set(LD_FLASH_SIZE 64K) -set(LD_FLASH_SIZE 224K) +set(LD_FLASH_SIZE 64K) +#set(LD_FLASH_SIZE 224K) set(LD_RAM_SIZE 20K) function(update_board TARGET) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index c2ed4d94e..486f0d2eb 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -338,8 +338,8 @@ def test_hid_composite_freertos(id): all_tests = [ 'cdc_dual_ports', 'cdc_msc', - 'cdc_msc_freertos', 'dfu', + 'cdc_msc_freertos', # dont test 2 cdc_msc next to each other, since they have same vid/pid. Can be confused by host 'dfu_runtime', 'hid_boot_interface', 'board_test' diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 5f218d073..688ea3822 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -66,7 +66,7 @@ "flasher": "jlink", "flasher_sn": "000611000000", "flasher_args": "-device MIMXRT1011xxx5A", - "comment": "sometime it is not enumerated/not reset, maybe need an bsp explicit disconnect/reconnect" + "comment": "not running reliably in bulk with other boards, probably power, flashing etc .." }, { "name": "espressif_s3_devkitm", -- cgit v1.3.1 From b8d3c0c4a8e005bcfcc4ed04556e6da54f235ccc Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Tue, 13 Aug 2024 23:57:01 +0700 Subject: Circi dynamic config (#2763) Circleci * build cmake armgcc and arm clang on circleci * use docker medium+ --- .circleci/config.yml | 105 +++++++++++--------------------------------- .circleci/config2.yml | 98 +++++++++++++++++++++++++++++++++++++++++ .github/workflows/build.yml | 19 ++++++-- tools/build_utils.py | 32 +++++++------- 4 files changed, 155 insertions(+), 99 deletions(-) create mode 100644 .circleci/config2.yml diff --git a/.circleci/config.yml b/.circleci/config.yml index 7b36bed7c..4d541a595 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,92 +1,39 @@ version: 2.1 -commands: - setup-toolchain: - parameters: - toolchain: - type: string - toolchain_url: - type: string - steps: -# - run: -# name: Make toolchain cache key -# command: echo "<< parameters.toolchain >>-<< parameters.toolchain_url>>" > toolchain_key -# - restore_cache: -# name: Restore Toolchain Cache -# key: deps-{{ checksum "toolchain_key" }} -# paths: -# - ~/cache/<< parameters.toolchain >> - - run: - name: Install Toolchain - command: | - # Only download if folder does not exist (not cached) - if [ ! -d ~/cache/<< parameters.toolchain >> ]; then - mkdir -p ~/cache/<< parameters.toolchain >> - wget << parameters.toolchain_url>> -O toolchain.tar.gz - tar -C ~/cache/<< parameters.toolchain >> -xaf toolchain.tar.gz - fi -# - save_cache: -# name: Save Toolchain Cache -# key: deps-{{ checksum "toolchain_key" }} -# paths: -# - ~/cache/<< parameters.toolchain >> - - run: - name: Setup build environment - command: | - echo "export PATH=$PATH:`echo ~/cache/<< parameters.toolchain >>/*/bin`" >> $BASH_ENV - # Install Ninja - NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-linux.zip - wget $NINJA_URL -O ninja-linux.zip - unzip ninja-linux.zip -d ~/bin - - get-deps: - parameters: - family: - type: string - steps: - - run: - name: Get Dependencies - command: | - python tools/get_deps.py << parameters.family >> +setup: true +orbs: + continuation: circleci/continuation@1 jobs: - arm-clang: - parameters: - family: - type: string - build-system: - type: string - + set-matrix: + executor: continuation/default docker: - image: cimg/base:current - resource_class: medium - environment: - TOOLCHAIN_URL: https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-17.0.1/LLVMEmbeddedToolchainForArm-17.0.1-Linux-x86_64.tar.xz + resource_class: small steps: - checkout - - setup-toolchain: - toolchain: clang - toolchain_url: $TOOLCHAIN_URL - - get-deps: - family: << parameters.family >> - run: - name: Build + name: Set matrix command: | - # Only build one board per family for non PRs i.e commit to master - ONE_PER_FAMILY="" - if [ -z "$CIRCLE_PULL_REQUEST" ]; then - ONE_PER_FAMILY="--one-per-family" - fi - python tools/build.py $ONE_PER_FAMILY -s << parameters.build-system >> --toolchain clang << parameters.family >> + MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py) + echo "MATRIX_JSON=$MATRIX_JSON" + + TOOLCHAIN_LIST=("arm-clang" "arm-gcc") + for toolchain in "${TOOLCHAIN_LIST[@]}"; do + FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\".family") + echo "${toolchain}_FAMILY=$FAMILY" + echo " - build:" >> .circleci/config2.yml + echo " matrix:" >> .circleci/config2.yml + echo " parameters:" >> .circleci/config2.yml + echo " toolchain: ['$toolchain']" >> .circleci/config2.yml + echo " build-system: ['cmake']" >> .circleci/config2.yml + echo " family: $FAMILY" >> .circleci/config2.yml + done + + - continuation/continue: + configuration_path: .circleci/config2.yml workflows: - build: + set-matrix: jobs: - - arm-clang: - matrix: - parameters: - build-system: - - cmake - #family: ['stm32f1'] - #family: ['stm32f1', 'stm32f2'] - family: ['imxrt', 'kinetis_k kinetis_kl kinetis_k32l2', 'lpc11 lpc13 lpc15', 'lpc17 lpc18 lpc40 lpc43', 'lpc51 lpc54 lpc55', 'nrf', 'samd11 samd21 saml2x', 'samd5x_e5x samg', 'stm32f0 stm32f1 stm32f2 stm32f3', 'stm32f4', 'stm32f7', 'stm32g0 stm32g4 stm32h5', 'stm32h7', 'stm32l4 stm32u5 stm32wb'] + - set-matrix diff --git a/.circleci/config2.yml b/.circleci/config2.yml new file mode 100644 index 000000000..ea7fccaff --- /dev/null +++ b/.circleci/config2.yml @@ -0,0 +1,98 @@ +version: 2.1 + +commands: + setup-toolchain: + parameters: + toolchain: + type: string + steps: + - run: + name: Install Toolchain + command: | + TOOLCHAIN_JSON='{ + "arm-clang": "https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-17.0.1/LLVMEmbeddedToolchainForArm-17.0.1-Linux-x86_64.tar.xz", + "arm-gcc": "https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v12.3.1-1.1/xpack-arm-none-eabi-gcc-12.3.1-1.1-linux-x64.tar.gz" + }' + toolchain_url=$(echo $TOOLCHAIN_JSON | jq -r '.["<< parameters.toolchain >>"]') + echo "toolchain_url=$toolchain_url" + + # download and extract toolchain + mkdir -p ~/cache/<< parameters.toolchain >> + wget $toolchain_url -O toolchain.tar.gz + tar -C ~/cache/<< parameters.toolchain >> -xaf toolchain.tar.gz + + # Add toolchain to PATH + echo "export PATH=$PATH:`echo ~/cache/<< parameters.toolchain >>/*/bin`" >> $BASH_ENV + + get-deps: + parameters: + family: + type: string + steps: + - run: + name: Get Dependencies + command: | + python tools/get_deps.py << parameters.family >> + + # Install Pico SDK + if [ << parameters.family >> == "rp2040" ]; then + git clone --depth 1 https://github.com/raspberrypi/pico-sdk.git ~/pico-sdk + echo "export PICO_SDK_PATH=~/pico-sdk" >> $BASH_ENV + fi + +jobs: + build: + parameters: + build-system: + type: string + toolchain: + type: string + family: + type: string + + docker: + - image: cimg/base:current + resource_class: medium+ + steps: + - checkout + - when: + condition: << parameters.build-system >> == 'cmake' + steps: + - run: + name: Install Ninja + command: | + # Install Ninja + NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-linux.zip + wget $NINJA_URL -O ninja-linux.zip + unzip ninja-linux.zip -d ~/bin + - setup-toolchain: + toolchain: << parameters.toolchain >> + - get-deps: + family: << parameters.family >> + - run: + name: Build + command: | + # Only build one board per family for non PRs i.e commit to master + ONE_PER_FAMILY="" + if [ -z "$CIRCLE_PULL_REQUEST" ]; then + ONE_PER_FAMILY="--one-per-family" + fi + + # Toolchain option default is gcc + if [ "<< parameters.toolchain >>" == "arm-clang" ]; then + TOOLCHAIN_OPTION="--toolchain clang" + elif [ "<< parameters.toolchain >>" == "arm-gcc" ]; then + TOOLCHAIN_OPTION="--toolchain gcc" + fi + + python tools/build.py $ONE_PER_FAMILY -s << parameters.build-system >> $TOOLCHAIN_OPTION << parameters.family >> + +workflows: + build: + jobs: +# - build: +# matrix: +# parameters: +# toolchain: ['arm-clang'] +# build-system: ['cmake'] +# family: ['imxrt'] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b3dc3ec42..fde9400a7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,9 +58,8 @@ jobs: fail-fast: false matrix: toolchain: - # - 'arm-clang' is built by circle-ci + # - 'arm-clang' is built by circle-ci in PR - 'aarch64-gcc' - - 'arm-gcc' - 'msp430-gcc' - 'riscv-gcc' with: @@ -69,6 +68,20 @@ jobs: build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} one-per-family: ${{ github.event_name != 'pull_request' }} + # --------------------------------------- + # Build CMake arm-gcc + # only build with push, for PR: all board is built by circle-ci + # --------------------------------------- + cmake-arm-gcc: + if: github.event_name == 'push' + needs: set-matrix + uses: ./.github/workflows/build_util.yml + with: + build-system: 'cmake' + toolchain: 'arm-gcc' + build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)['arm-gcc'].family) }} + one-per-family: true + # --------------------------------------- # Build Make # --------------------------------------- @@ -80,7 +93,7 @@ jobs: fail-fast: false matrix: toolchain: - # 'arm-clang' is built by circle-ci + # 'arm-clang' would be built by circle-ci - 'aarch64-gcc' - 'arm-gcc' - 'msp430-gcc' diff --git a/tools/build_utils.py b/tools/build_utils.py index b66b64b97..32aca95dd 100644 --- a/tools/build_utils.py +++ b/tools/build_utils.py @@ -81,6 +81,19 @@ def skip_example(example, board): return False +def build_size(make_cmd): + size_output = subprocess.run(make_cmd + ' size', shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8").splitlines() + for i, l in enumerate(size_output): + text_title = 'text data bss dec' + if text_title in l: + size_list = size_output[i+1].split('\t') + flash_size = int(size_list[0]) + sram_size = int(size_list[1]) + int(size_list[2]) + return (flash_size, sram_size) + + return (0, 0) + + def build_example(example, board, make_option): start_time = time.monotonic() flash_size = "-" @@ -89,7 +102,7 @@ def build_example(example, board, make_option): # succeeded, failed, skipped ret = [0, 0, 0] - make_cmd = "make -j -C examples/{} BOARD={} {}".format(example, board, make_option) + make_cmd = f"make -j -C examples/{example} BOARD={board} {make_option}" # Check if board is skipped if skip_example(example, board): @@ -97,14 +110,12 @@ def build_example(example, board, make_option): ret[2] = 1 print(build_format.format(example, board, status, '-', flash_size, sram_size)) else: - #subprocess.run(make_cmd + " clean", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - build_result = subprocess.run(make_cmd + " all", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + build_result = subprocess.run(f"{make_cmd} all", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if build_result.returncode == 0: status = SUCCEEDED ret[0] = 1 (flash_size, sram_size) = build_size(make_cmd) - #subprocess.run(make_cmd + " copy-artifact", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) else: status = FAILED ret[1] = 1 @@ -116,16 +127,3 @@ def build_example(example, board, make_option): print(build_result.stdout.decode("utf-8")) return ret - - -def build_size(make_cmd): - size_output = subprocess.run(make_cmd + ' size', shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8").splitlines() - for i, l in enumerate(size_output): - text_title = 'text data bss dec' - if text_title in l: - size_list = size_output[i+1].split('\t') - flash_size = int(size_list[0]) - sram_size = int(size_list[1]) + int(size_list[2]) - return (flash_size, sram_size) - - return (0, 0) -- cgit v1.3.1 From f6b96f7ea9f0d0c4872e1e290bf59f65c68a7bf3 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Aug 2024 22:56:59 +0700 Subject: fix spelling, add max32 to ci with arm-gcc build --- .github/workflows/ci_set_matrix.py | 1 + src/portable/mentor/musb/musb_ti.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index a56bd4214..c9698c934 100644 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -22,6 +22,7 @@ family_list = { "lpc11 lpc13 lpc15": ["arm-gcc", "arm-clang"], "lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"], "lpc51 lpc54 lpc55": ["arm-gcc", "arm-clang"], + "max32650 max32666 max32690 max78002": ["arm-gcc"], "mcx": ["arm-gcc"], "mm32": ["arm-gcc"], "msp430": ["msp430-gcc"], diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index dbf82f391..4c9f00278 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -43,7 +43,7 @@ #endif -// Header supports both device and host modes. Only include whats necessary +// Header supports both device and host modes. Only include what's necessary #if CFG_TUD_ENABLED // Mapping of peripheral instances to port. Currently just 1. -- cgit v1.3.1 From 0be427bae95ef0fe94cb6f0b405eb5c3bbae160a Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Aug 2024 23:59:35 +0700 Subject: use max32 cmsis, fix NVIC_GetEnableIRQ() not defined when using with CMISIS < 5 --- hw/bsp/max32650/family.c | 16 ++++++++++++++-- hw/bsp/max32650/family.cmake | 1 - hw/bsp/max32650/family.mk | 3 +-- hw/bsp/max32666/family.c | 15 +++++++++++++-- hw/bsp/max32666/family.cmake | 1 - hw/bsp/max32666/family.mk | 1 - hw/bsp/max32690/family.c | 16 ++++++++++++++-- hw/bsp/max32690/family.cmake | 1 - hw/bsp/max32690/family.mk | 1 - hw/bsp/max78002/family.c | 15 +++++++++++++-- hw/bsp/max78002/family.cmake | 1 - hw/bsp/max78002/family.mk | 1 - src/portable/mentor/musb/musb_max32.h | 33 ++++++++++++++------------------- tools/get_deps.py | 2 +- 14 files changed, 70 insertions(+), 37 deletions(-) diff --git a/hw/bsp/max32650/family.c b/hw/bsp/max32650/family.c index 16b5233b9..89a5db160 100644 --- a/hw/bsp/max32650/family.c +++ b/hw/bsp/max32650/family.c @@ -24,12 +24,24 @@ * This file is part of the TinyUSB stack. */ -#include "board.h" -#include "bsp/board_api.h" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" // _mxc_crit_get_state() +#endif + #include "gpio.h" +#include "mxc_sys.h" #include "mxc_device.h" #include "uart.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#include "board.h" +#include "bsp/board_api.h" + + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ diff --git a/hw/bsp/max32650/family.cmake b/hw/bsp/max32650/family.cmake index 92b68a1cd..8c4f286a2 100644 --- a/hw/bsp/max32650/family.cmake +++ b/hw/bsp/max32650/family.cmake @@ -74,7 +74,6 @@ function(add_board_target BOARD_TARGET) ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include ${MAX32_CMSIS}/Include ${MAX32_CMSIS}/Device/Maxim/MAX32650/Include ${MAX32_PERIPH}/Include/MAX32650 diff --git a/hw/bsp/max32650/family.mk b/hw/bsp/max32650/family.mk index 359261216..d2fc293e4 100644 --- a/hw/bsp/max32650/family.mk +++ b/hw/bsp/max32650/family.mk @@ -82,14 +82,13 @@ SRC_C += \ $(PERIPH_SRC)/ICC/icc_reva.c \ $(PERIPH_SRC)/ICC/icc_common.c \ $(PERIPH_SRC)/TPU/tpu_me10.c \ - $(PERIPH_SRC)/TPU/tpu_reva.c \ + $(PERIPH_SRC)/TPU/tpu_reva.c \ $(PERIPH_SRC)/UART/uart_common.c \ $(PERIPH_SRC)/UART/uart_me10.c \ $(PERIPH_SRC)/UART/uart_reva.c \ INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(MAX32_CMSIS)/Include \ $(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX32650/Include \ $(TOP)/$(MAX32_PERIPH)/Include/MAX32650 \ diff --git a/hw/bsp/max32666/family.c b/hw/bsp/max32666/family.c index 1398e09ff..8ee4b6762 100644 --- a/hw/bsp/max32666/family.c +++ b/hw/bsp/max32666/family.c @@ -24,13 +24,24 @@ * This file is part of the TinyUSB stack. */ -#include "board.h" -#include "bsp/board_api.h" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" // _mxc_crit_get_state() +#endif + #include "gpio.h" +#include "mxc_sys.h" #include "mcr_regs.h" #include "mxc_device.h" #include "uart.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#include "board.h" +#include "bsp/board_api.h" + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ diff --git a/hw/bsp/max32666/family.cmake b/hw/bsp/max32666/family.cmake index eb9d2175f..4a3f1a428 100644 --- a/hw/bsp/max32666/family.cmake +++ b/hw/bsp/max32666/family.cmake @@ -70,7 +70,6 @@ function(add_board_target BOARD_TARGET) ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include ${MAX32_CMSIS}/Include ${MAX32_CMSIS}/Device/Maxim/MAX32665/Include ${MAX32_PERIPH}/Include/MAX32665 diff --git a/hw/bsp/max32666/family.mk b/hw/bsp/max32666/family.mk index 720d994ef..b4f7d1e57 100644 --- a/hw/bsp/max32666/family.mk +++ b/hw/bsp/max32666/family.mk @@ -82,7 +82,6 @@ SRC_C += \ INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(MAX32_CMSIS)/Include \ $(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX32665/Include \ $(TOP)/$(MAX32_PERIPH)/Include/MAX32665 \ diff --git a/hw/bsp/max32690/family.c b/hw/bsp/max32690/family.c index f4998bdbe..2418168d4 100644 --- a/hw/bsp/max32690/family.c +++ b/hw/bsp/max32690/family.c @@ -24,13 +24,25 @@ * This file is part of the TinyUSB stack. */ -#include "board.h" -#include "bsp/board_api.h" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" // _mxc_crit_get_state() +#endif + #include "gpio.h" +#include "mxc_sys.h" #include "mcr_regs.h" #include "mxc_device.h" #include "uart.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#include "board.h" +#include "bsp/board_api.h" + + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ diff --git a/hw/bsp/max32690/family.cmake b/hw/bsp/max32690/family.cmake index 2a9422dbe..58647e432 100644 --- a/hw/bsp/max32690/family.cmake +++ b/hw/bsp/max32690/family.cmake @@ -75,7 +75,6 @@ function(add_board_target BOARD_TARGET) ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include ${MAX32_CMSIS}/Include ${MAX32_CMSIS}/Device/Maxim/MAX32690/Include ${MAX32_PERIPH}/Include/MAX32690 diff --git a/hw/bsp/max32690/family.mk b/hw/bsp/max32690/family.mk index c533cf4a4..d4df8ef2f 100644 --- a/hw/bsp/max32690/family.mk +++ b/hw/bsp/max32690/family.mk @@ -90,7 +90,6 @@ SRC_C += \ INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(MAX32_CMSIS)/Include \ $(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX32690/Include \ $(TOP)/$(MAX32_PERIPH)/Include/MAX32690 \ diff --git a/hw/bsp/max78002/family.c b/hw/bsp/max78002/family.c index 7758083a2..8d51f141c 100644 --- a/hw/bsp/max78002/family.c +++ b/hw/bsp/max78002/family.c @@ -24,13 +24,24 @@ * This file is part of the TinyUSB stack. */ -#include "board.h" -#include "bsp/board_api.h" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" // _mxc_crit_get_state() +#endif + #include "gpio.h" +#include "mxc_sys.h" #include "mcr_regs.h" #include "mxc_device.h" #include "uart.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#include "board.h" +#include "bsp/board_api.h" + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ diff --git a/hw/bsp/max78002/family.cmake b/hw/bsp/max78002/family.cmake index 090f1da43..446930bd8 100644 --- a/hw/bsp/max78002/family.cmake +++ b/hw/bsp/max78002/family.cmake @@ -72,7 +72,6 @@ function(add_board_target BOARD_TARGET) ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include ${MAX32_CMSIS}/Include ${MAX32_CMSIS}/Device/Maxim/MAX78002/Include ${MAX32_PERIPH}/Include/MAX78002 diff --git a/hw/bsp/max78002/family.mk b/hw/bsp/max78002/family.mk index 5297815de..997816261 100644 --- a/hw/bsp/max78002/family.mk +++ b/hw/bsp/max78002/family.mk @@ -87,7 +87,6 @@ SRC_C += \ INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(MAX32_CMSIS)/Include \ $(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX78002/Include \ $(TOP)/$(MAX32_PERIPH)/Include/MAX78002 \ diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 297a695f8..bc6ce76dd 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -31,13 +31,8 @@ extern "C" { #endif -#if TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002) - #include "mxc_device.h" - #include "usbhs_regs.h" -#else - #error "Unsupported MCUs" -#endif - +#include "mxc_device.h" +#include "usbhs_regs.h" #if CFG_TUD_ENABLED #define USBHS_M31_CLOCK_RECOVERY @@ -48,39 +43,39 @@ static mxc_usbhs_regs_t* const musb_periph_inst[] = { }; // Mapping of IRQ numbers to port. Currently just 1. -static const IRQn_Type musb_irqs[] = { +static const IRQn_Type musb_irqs[] = { USB_IRQn }; TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_enable(uint8_t rhport) -{ +static inline void musb_dcd_int_enable(uint8_t rhport) { NVIC_EnableIRQ(musb_irqs[rhport]); } TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_disable(uint8_t rhport) -{ +static inline void musb_dcd_int_disable(uint8_t rhport) { NVIC_DisableIRQ(musb_irqs[rhport]); } TU_ATTR_ALWAYS_INLINE -static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) -{ +static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) { + #ifdef NVIC_GetEnableIRQ // only defined in CMSIS 5 return NVIC_GetEnableIRQ(musb_irqs[rhport]); + #else + uint32_t IRQn = (uint32_t) musb_irqs[rhport]; + return ((NVIC->ISER[IRQn >> 5UL] & (1UL << (IRQn & 0x1FUL))) != 0UL) ? 1UL : 0UL; + #endif } TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_clear(uint8_t rhport) -{ - NVIC_ClearPendingIRQ(musb_irqs[rhport]); +static inline void musb_dcd_int_clear(uint8_t rhport) { + NVIC_ClearPendingIRQ(musb_irqs[rhport]); } //Used to save and restore user's register map when interrupt occurs static volatile unsigned isr_saved_index = 0; -static inline void musb_dcd_int_handler_enter(uint8_t rhport) -{ +static inline void musb_dcd_int_handler_enter(uint8_t rhport) { uint32_t mxm_int, mxm_int_en, mxm_is; //save current register index diff --git a/tools/get_deps.py b/tools/get_deps.py index 51d6304ae..f141d3d41 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -26,7 +26,7 @@ deps_optional = { 'fc100s'], 'hw/mcu/analog/max32' : ['https://github.com/analogdevicesinc/msdk.git', 'b20b398d3e5e2007594e54a74ba3d2a2e50ddd75', - 'max32690 max32650 max32666 max78002'], + 'max32650 max32666 max32690 max78002'], 'hw/mcu/bridgetek/ft9xx/ft90x-sdk': ['https://github.com/BRTSG-FOSS/ft90x-sdk.git', '91060164afe239fcb394122e8bf9eb24d3194eb1', 'brtmm90x'], -- cgit v1.3.1 From 1402e6ec0d5ed60375c9deb1add9061fcb37e590 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Aug 2024 14:36:31 +0700 Subject: add flash-uniflash support for ti tm4c --- README.rst | 4 +- examples/build_system/make/rules.mk | 5 ++ hw/bsp/family_support.cmake | 15 ++++ hw/bsp/tm4c/boards/ek_tm4c123gxl/board.cmake | 1 + hw/bsp/tm4c/boards/ek_tm4c123gxl/board.mk | 2 + .../tm4c/boards/ek_tm4c123gxl/ek_tm4c123gxl.ccxml | 17 +++++ hw/bsp/tm4c/family.c | 83 ++++++++++------------ hw/bsp/tm4c/family.cmake | 1 + test/hil/hil_test.py | 5 ++ 9 files changed, 85 insertions(+), 48 deletions(-) create mode 100644 hw/bsp/tm4c/boards/ek_tm4c123gxl/ek_tm4c123gxl.ccxml diff --git a/README.rst b/README.rst index 1ae8c5375..422f23271 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -|Build Status| |Documentation Status| |Fuzzing Status| |License| +|Build Status| |CircleCI Status| |Documentation Status| |Fuzzing Status| |License| Sponsors ======== @@ -197,6 +197,8 @@ Docs .. |Build Status| image:: https://github.com/hathach/tinyusb/actions/workflows/cmake_arm.yml/badge.svg :target: https://github.com/hathach/tinyusb/actions +.. |CircleCI Status| image:: https://dl.circleci.com/status-badge/img/circleci/4AYHvUhFxdnY4rA7LEsdqW/QmrpoL2AjGqetvFQNqtWyq/tree/master.svg?style=svg + :target: https://dl.circleci.com/status-badge/redirect/circleci/4AYHvUhFxdnY4rA7LEsdqW/QmrpoL2AjGqetvFQNqtWyq/tree/master .. |Documentation Status| image:: https://readthedocs.org/projects/tinyusb/badge/?version=latest :target: https://docs.tinyusb.org/en/latest/?badge=latest .. |Fuzzing Status| image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/tinyusb.svg diff --git a/examples/build_system/make/rules.mk b/examples/build_system/make/rules.mk index f322dbae6..86de17b6c 100644 --- a/examples/build_system/make/rules.mk +++ b/examples/build_system/make/rules.mk @@ -166,6 +166,11 @@ flash-bmp: $(BUILD)/$(PROJECT).elf debug-bmp: $(BUILD)/$(PROJECT).elf $(GDB) -ex 'target extended-remote $(BMP)' -ex 'monitor swdp_scan' -ex 'attach 1' $< +# --------------- TI Uniflash ----------------- +DSLITE ?= dslite.sh +flash-uniflash: $(BUILD)/$(PROJECT).hex + ${DSLITE} ${UNIFLASH_OPTION} -f $< + #-------------- Artifacts -------------- # Create binary directory diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 03a24c95b..4a31f6218 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -573,6 +573,21 @@ function(family_flash_msp430flasher TARGET) ) endfunction() + +function(family_flash_uniflash TARGET) + if (NOT DEFINED DSLITE) + set(DSLITE dslite.sh) + endif () + + separate_arguments(OPTION_LIST UNIX_COMMAND ${UNIFLASH_OPTION}) + + add_custom_target(${TARGET}-uniflash + DEPENDS ${TARGET} + COMMAND ${DSLITE} ${UNIFLASH_OPTION} -f $/${TARGET}.hex + VERBATIM + ) +endfunction() + #---------------------------------- # Family specific #---------------------------------- diff --git a/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.cmake b/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.cmake index a86b5c0e5..b8df9f189 100644 --- a/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.cmake +++ b/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.cmake @@ -4,6 +4,7 @@ set(JLINK_DEVICE TM4C123GH6PM) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/tm4c123.ld) set(OPENOCD_OPTION "-f board/ti_ek-tm4c123gxl.cfg") +set(UNIFLASH_OPTION "-c ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ccxml -r 1") function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC diff --git a/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.mk b/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.mk index a3e8df62c..b3ded8007 100644 --- a/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.mk +++ b/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.mk @@ -10,4 +10,6 @@ JLINK_DEVICE = TM4C123GH6PM # flash using openocd OPENOCD_OPTION = -f board/ti_ek-tm4c123gxl.cfg +UNIFLASH_OPTION = -c ${TOP}/${BOARD_PATH}/${BOARD}.ccxml -r 1 + flash: flash-openocd diff --git a/hw/bsp/tm4c/boards/ek_tm4c123gxl/ek_tm4c123gxl.ccxml b/hw/bsp/tm4c/boards/ek_tm4c123gxl/ek_tm4c123gxl.ccxml new file mode 100644 index 000000000..426a6f368 --- /dev/null +++ b/hw/bsp/tm4c/boards/ek_tm4c123gxl/ek_tm4c123gxl.ccxml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/hw/bsp/tm4c/family.c b/hw/bsp/tm4c/family.c index 738bc3fa0..5e1f6d3ff 100644 --- a/hw/bsp/tm4c/family.c +++ b/hw/bsp/tm4c/family.c @@ -5,8 +5,7 @@ //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB0_Handler(void) -{ +void USB0_Handler(void) { #if CFG_TUH_ENABLED tuh_int_handler(0, true); #endif @@ -20,8 +19,7 @@ void USB0_Handler(void) // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ -static void board_uart_init (void) -{ +static void board_uart_init(void) { SYSCTL->RCGCUART |= (1 << 0); // Enable the clock to UART0 SYSCTL->RCGCGPIO |= (1 << 0); // Enable the clock to GPIOA @@ -42,13 +40,12 @@ static void board_uart_init (void) UART0->CTL = (1 << 0) | (1 << 8) | (1 << 9); // UART0 Enable, Transmit Enable, Receive Enable } -static void initialize_board_led (GPIOA_Type *port, uint8_t PinMsk, uint8_t dirmsk) -{ +static void initialize_board_led(GPIOA_Type* port, uint8_t PinMsk, uint8_t dirmsk) { /* Enable PortF Clock */ SYSCTL->RCGCGPIO |= (1 << 5); /* Let the clock stabilize */ - while ( !((SYSCTL->PRGPIO) & (1 << 5)) ) {} + while (!((SYSCTL->PRGPIO) & (1 << 5))) {} /* Port Digital Enable */ port->DEN |= PinMsk; @@ -57,46 +54,33 @@ static void initialize_board_led (GPIOA_Type *port, uint8_t PinMsk, uint8_t dirm port->DIR = dirmsk; } -static void board_switch_init (void) -{ - GPIOF->DIR &= ~(1 << BOARD_BTN); - GPIOF->PUR |= (1 << BOARD_BTN); - GPIOF->DEN |= (1 << BOARD_BTN); -} - -static void WriteGPIOPin (GPIOA_Type *port, uint8_t PinMsk, bool state) -{ - if ( state ) - { +static void WriteGPIOPin(GPIOA_Type* port, uint8_t PinMsk, bool state) { + if (state) { port->DATA |= PinMsk; - } - else - { + } else { port->DATA &= ~(PinMsk); } } -static uint32_t ReadGPIOPin (GPIOA_Type *port, uint8_t pinMsk) -{ +static uint32_t ReadGPIOPin(GPIOA_Type* port, uint8_t pinMsk) { return (port->DATA & pinMsk); } -void board_init (void) -{ +void board_init(void) { SystemCoreClockUpdate(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS - // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif /* Reset USB */ SYSCTL->SRCR2 |= (1u << 16); - for ( volatile uint8_t i = 0; i < 20; i++ ) {} + for (volatile uint8_t i = 0; i < 20; i++) {} SYSCTL->SRCR2 &= ~(1u << 16); @@ -110,7 +94,7 @@ void board_init (void) SYSCTL->RCGCGPIO |= (1u << 3); /* Let the clock stabilize */ - while ( !(SYSCTL->PRGPIO & (1u << 3)) ) {} + while (!(SYSCTL->PRGPIO & (1u << 3))) {} /* USB IOs to Analog Mode */ GPIOD->AFSEL &= ~((1u << 4) | (1u << 5)); @@ -124,7 +108,9 @@ void board_init (void) initialize_board_led(LED_PORT, leds, dirmsk); /* Configure GPIO for board switch */ - board_switch_init(); + GPIOF->DIR &= ~(1 << BOARD_BTN); + GPIOF->PUR |= (1 << BOARD_BTN); + GPIOF->DEN |= (1 << BOARD_BTN); /* Initialize board UART */ board_uart_init(); @@ -132,32 +118,35 @@ void board_init (void) TU_LOG1_INT(SystemCoreClock); } -void board_led_write (bool state) -{ +void board_led_write(bool state) { WriteGPIOPin(LED_PORT, (1 << LED_PIN_BLUE), state); } -uint32_t board_button_read (void) -{ +uint32_t board_button_read(void) { uint32_t gpio_value = ReadGPIOPin(BOARD_BTN_PORT, BOARD_BTN_Msk); return BUTTON_STATE_ACTIVE ? gpio_value : !gpio_value; } -int board_uart_write (void const *buf, int len) -{ - uint8_t const * data = buf; +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + uint8_t const len = 8; + // Note: DID0, DID1 are variant ID, they aer used since TM4C123 does not have unique ID + memcpy(id, (void*)(uintptr_t) &SYSCTL->DID0, len); + return len; +} - for ( int i = 0; i < len; i++ ) - { - while ( (UART0->FR & (1 << 5)) != 0 ) {} // Poll until previous data was shofted out - UART0->DR = data[i]; // Write UART0 DATA REGISTER +int board_uart_write(void const* buf, int len) { + uint8_t const* data = buf; + + for (int i = 0; i < len; i++) { + while ((UART0->FR & (1 << 5)) != 0) {} // Poll until previous data was shofted out + UART0->DR = data[i]; // Write UART0 DATA REGISTER } return len; } -int board_uart_read (uint8_t *buf, int len) -{ +int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; @@ -165,13 +154,13 @@ int board_uart_read (uint8_t *buf, int len) #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -void SysTick_Handler (void) -{ + +void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis (void) -{ +uint32_t board_millis(void) { return system_ticks; } + #endif diff --git a/hw/bsp/tm4c/family.cmake b/hw/bsp/tm4c/family.cmake index 86db985d6..9c083759b 100644 --- a/hw/bsp/tm4c/family.cmake +++ b/hw/bsp/tm4c/family.cmake @@ -92,4 +92,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_add_bin_hex(${TARGET}) family_flash_openocd(${TARGET}) + family_flash_uniflash(${TARGET}) endfunction() diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 486f0d2eb..1d5f98e5c 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -196,6 +196,11 @@ def flash_esptool(board, firmware): return ret +def flash_uniflash(board, firmware): + ret = run_cmd(f'dslite.sh {board["flasher_args"]} -f {firmware}.hex') + return ret + + # ------------------------------------------------------------- # Tests # ------------------------------------------------------------- -- cgit v1.3.1 From a9df933e0d35c1c198343464d49e69eff20dde4a Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Aug 2024 15:24:04 +0700 Subject: add TUP_USBIP_MUSB macro, minor rename --- src/common/tusb_mcu.h | 6 ++--- src/portable/mentor/musb/dcd_musb.c | 50 +++++++++++++++++------------------ src/portable/mentor/musb/musb_max32.h | 18 ++++++------- src/portable/mentor/musb/musb_ti.h | 18 ++++++------- src/portable/mentor/musb/musb_type.h | 6 ++--- 5 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 259b9e002..7ec3c5842 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -308,6 +308,7 @@ #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) + #define TUP_USBIP_MUSB #define TUP_DCD_ENDPOINT_MAX 8 //--------------------------------------------------------------------+ @@ -471,12 +472,11 @@ //--------------------------------------------------------------------+ // Analog Devices //--------------------------------------------------------------------+ -#elif TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32666, \ - OPT_MCU_MAX32650, OPT_MCU_MAX78002) +#elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002) + #define TUP_USBIP_MUSB #define TUP_DCD_ENDPOINT_MAX 12 #define TUP_RHPORT_HIGHSPEED 1 - #endif //--------------------------------------------------------------------+ diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index ee36656fd..80dfb9235 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -27,7 +27,7 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED +#if CFG_TUD_ENABLED && defined(TUP_USBIP_MUSB) #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) /* GCC warns that an address may be unaligned, even though @@ -155,7 +155,7 @@ static void process_setup_packet(uint8_t rhport) { uint32_t *p = (void*)&_dcd.setup_packet; volatile uint32_t *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, 0); - volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); p[0] = *fifo_ptr; p[1] = *fifo_ptr; @@ -183,7 +183,7 @@ static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) return true; } - volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); + volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); const unsigned mps = regs->TXMAXP; const unsigned len = TU_MIN(mps, rem); void *buf = pipe->buf; @@ -208,7 +208,7 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) unsigned epnum = tu_edpt_number(ep_addr); unsigned epnum_minus1 = epnum - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; - volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); + volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, regs->RXCSRL); TU_ASSERT(regs->RXCSRL & USB_RXCSRL1_RXRDY); @@ -250,7 +250,7 @@ static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16 if (dir_in) { handle_xfer_in(rhport, ep_addr); } else { - volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); + volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); if (regs->RXCSRL & USB_RXCSRL1_RXRDY) regs->RXCSRL = 0; } return true; @@ -260,7 +260,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ { (void)rhport; TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ - volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); const unsigned req = _dcd.setup_packet.bmRequestType; TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); @@ -325,7 +325,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ static void process_ep0(uint8_t rhport) { - volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); uint_fast8_t csrl = ep0_regs->CSRL0; // TU_LOG1(" EP0 ep0_regs->CSRL0 = %x\r\n", csrl); @@ -381,7 +381,7 @@ static void process_ep0(uint8_t rhport) return; } - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); /* When CSRL0 is zero, it means that completion of sending a any length packet * or receiving a zero length packet. */ @@ -415,7 +415,7 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) const unsigned epn = tu_edpt_number(ep_addr); const unsigned epn_minus1 = epn - 1; - volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); + volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); if (dir_in) { // TU_LOG1(" TXCSRL%d = %x\r\n", epn, regs->TXCSRL); if (regs->TXCSRL & USB_TXCSRL1_STALLED) { @@ -442,7 +442,7 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) static void process_bus_reset(uint8_t rhport) { - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), * a control transfer state is SETUP or STATUS stage. */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; @@ -467,7 +467,7 @@ static void process_bus_reset(uint8_t rhport) void dcd_init(uint8_t rhport) { - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); ctrl_regs->IE |= USB_IE_SUSPND; musb_dcd_int_clear(rhport); musb_dcd_phy_init(rhport); @@ -488,7 +488,7 @@ void dcd_int_disable(uint8_t rhport) void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void)dev_addr; - volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; @@ -499,7 +499,7 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) // Wake up host void dcd_remote_wakeup(uint8_t rhport) { - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); ctrl_regs->POWER |= USB_POWER_RESUME; unsigned cnt = SystemCoreClock / 1000; @@ -511,7 +511,7 @@ void dcd_remote_wakeup(uint8_t rhport) // Connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); ctrl_regs->POWER |= TUD_OPT_HIGH_SPEED ? USB_POWER_HSENAB : 0; ctrl_regs->POWER |= USB_POWER_SOFTCONN; } @@ -519,7 +519,7 @@ void dcd_connect(uint8_t rhport) // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); ctrl_regs->POWER &= ~USB_POWER_SOFTCONN; } @@ -551,8 +551,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) pipe->length = 0; pipe->remaining = 0; - volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); if (dir_in) { regs->TXMAXP = mps; regs->TXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0; @@ -579,8 +579,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) void dcd_edpt_close_all(uint8_t rhport) { - volatile musb_dcd_epn_regs_t *regs; - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_epn_regs_t *regs; + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); ctrl_regs->TXIE = 1; /* Enable only EP0 */ @@ -613,8 +613,8 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) unsigned const epn = tu_edpt_number(ep_addr); unsigned const dir_in = tu_edpt_dir(ep_addr); - volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (dir_in) { @@ -679,14 +679,14 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (0 == epn) { - volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); if (!ep_addr) { /* Ignore EP80 */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.pipe0.buf = NULL; ep0_regs->CSRL0 = USB_CSRL0_STALL; } } else { - volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); + volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); if (tu_edpt_dir(ep_addr)) { /* IN */ regs->TXCSRL = USB_TXCSRL1_STALL; } else { /* OUT */ @@ -702,7 +702,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; unsigned const epn = tu_edpt_number(ep_addr); - musb_dcd_epn_regs_t volatile *regs = musb_dcd_epn_regs(rhport, epn); + musb_epn_regs_t volatile *regs = musb_dcd_epn_regs(rhport, epn); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (tu_edpt_dir(ep_addr)) { /* IN */ @@ -719,7 +719,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) void dcd_int_handler(uint8_t rhport) { uint_fast8_t is, txis, rxis; - volatile musb_dcd_ctl_regs_t *ctrl_regs; + volatile musb_ctl_regs_t *ctrl_regs; //Part specific ISR setup/entry musb_dcd_int_handler_enter(rhport); diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index bc6ce76dd..0712aeda4 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_MUSB_MAX32_H_ -#define _TUSB_MUSB_MAX32_H_ +#ifndef TUSB_MUSB_MAX32_H_ +#define TUSB_MUSB_MAX32_H_ #ifdef __cplusplus extern "C" { @@ -136,25 +136,25 @@ static inline void musb_dcd_phy_init(uint8_t rhport) musb_periph_inst[rhport]->m31_phy_ponrst = 1; } -static inline volatile musb_dcd_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) +static inline volatile musb_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) { - volatile musb_dcd_ctl_regs_t *regs = (volatile musb_dcd_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->faddr)); + volatile musb_ctl_regs_t *regs = (volatile musb_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->faddr)); return regs; } -static inline volatile musb_dcd_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) +static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) { //Need to set index to map EP registers musb_periph_inst[rhport]->index = epnum; - volatile musb_dcd_epn_regs_t *regs = (volatile musb_dcd_epn_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->inmaxp)); + volatile musb_epn_regs_t *regs = (volatile musb_epn_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->inmaxp)); return regs; } -static inline volatile musb_dcd_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) +static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) { //Need to set index to map EP0 registers musb_periph_inst[rhport]->index = 0; - volatile musb_dcd_ep0_regs_t *regs = (volatile musb_dcd_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->csr0)); + volatile musb_ep0_regs_t *regs = (volatile musb_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->csr0)); return regs; } @@ -213,4 +213,4 @@ static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned } #endif -#endif // _TUSB_MUSB_MAX32_H_ +#endif // TUSB_MUSB_MAX32_H_ diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index 4c9f00278..ec0a267b1 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_MUSB_TI_H_ -#define _TUSB_MUSB_TI_H_ +#ifndef TUSB_MUSB_TI_H_ +#define TUSB_MUSB_TI_H_ #ifdef __cplusplus extern "C" { @@ -95,25 +95,25 @@ static inline void musb_dcd_int_handler_exit(uint8_t rhport){ //Nothing to do for this part } -static inline volatile musb_dcd_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) +static inline volatile musb_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) { - volatile musb_dcd_ctl_regs_t *regs = (volatile musb_dcd_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->FADDR)); + volatile musb_ctl_regs_t *regs = (volatile musb_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->FADDR)); return regs; } -static inline volatile musb_dcd_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) +static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) { uintptr_t baseptr = (uintptr_t)&(musb_periph_inst[rhport]->TXMAXP1); //On the TI parts, the epn registers are 16-bytes apart. The core regs defined //by musb_dcd_epn_regs and 6 reserved/other use bytes - volatile musb_dcd_epn_regs_t *regs = (volatile musb_dcd_epn_regs_t*)(baseptr + ((epnum - 1)*16)); + volatile musb_epn_regs_t *regs = (volatile musb_epn_regs_t*)(baseptr + ((epnum - 1) * 16)); return regs; } -static inline volatile musb_dcd_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) +static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) { - volatile musb_dcd_ep0_regs_t *regs = (volatile musb_dcd_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->CSRL0)); + volatile musb_ep0_regs_t *regs = (volatile musb_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->CSRL0)); return regs; } @@ -282,4 +282,4 @@ static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned } #endif -#endif // _TUSB_MUSB_TI_H_ +#endif // TUSB_MUSB_TI_H_ diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index e8af8f19b..d21dcd6da 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -50,7 +50,7 @@ typedef struct TU_ATTR_PACKED { uint8_t RXCSRL; uint8_t RXCSRH; uint16_t RXCOUNT; -} musb_dcd_epn_regs_t; +} musb_epn_regs_t; // Endpoint 0 register mapping. typedef struct TU_ATTR_PACKED { @@ -58,7 +58,7 @@ typedef struct TU_ATTR_PACKED { uint8_t CSRH0; uint32_t RESERVED; uint8_t COUNT0; -} musb_dcd_ep0_regs_t; +} musb_ep0_regs_t; // Control register mapping typedef struct TU_ATTR_PACKED { @@ -70,7 +70,7 @@ typedef struct TU_ATTR_PACKED { uint16_t RXIE; uint8_t IS; uint8_t IE; -} musb_dcd_ctl_regs_t; +} musb_ctl_regs_t; //***************************************************************************** // -- cgit v1.3.1 From e339702a2a7977e4e62c2f3fea9aca55f71190ee Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Aug 2024 16:41:20 +0700 Subject: adding universal register structs for musb --- src/portable/mentor/musb/dcd_musb.c | 99 +++++++++++---------- src/portable/mentor/musb/musb_max32.h | 47 ++++------ src/portable/mentor/musb/musb_ti.h | 8 +- src/portable/mentor/musb/musb_type.h | 156 +++++++++++++++++++++++++++++++--- 4 files changed, 216 insertions(+), 94 deletions(-) diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 80dfb9235..78fc3d616 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -54,6 +54,8 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); #error "Unsupported MCU" #endif +#define MUSB_REGS(rhport) ((musb_regs_t*) MUSB_BASES[rhport]) + /*------------------------------------------------------------------ * MACRO TYPEDEF CONSTANT ENUM DECLARATION *------------------------------------------------------------------*/ @@ -381,7 +383,7 @@ static void process_ep0(uint8_t rhport) return; } - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + musb_regs_t* musb_regs = MUSB_REGS(rhport); /* When CSRL0 is zero, it means that completion of sending a any length packet * or receiving a zero length packet. */ @@ -389,7 +391,7 @@ static void process_ep0(uint8_t rhport) /* STATUS IN */ if (*(const uint16_t*)(uintptr_t)&_dcd.setup_packet == 0x0500) { /* The address must be changed on completion of the control transfer. */ - ctrl_regs->FADDR = (uint8_t)_dcd.setup_packet.wValue; + musb_regs->faddr = (uint8_t)_dcd.setup_packet.wValue; } _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; dcd_event_xfer_complete(rhport, @@ -442,7 +444,7 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) static void process_bus_reset(uint8_t rhport) { - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + musb_regs_t* musb_regs = MUSB_REGS(rhport); /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), * a control transfer state is SETUP or STATUS stage. */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; @@ -450,15 +452,15 @@ static void process_bus_reset(uint8_t rhport) /* When pipe0.buf has not NULL, DATA stage works in progress. */ _dcd.pipe0.buf = NULL; - ctrl_regs->TXIE = 1; /* Enable only EP0 */ - ctrl_regs->RXIE = 0; + musb_regs->intr_txen = 1; /* Enable only EP0 */ + musb_regs->intr_rxen = 0; /* Clear FIFO settings */ for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { musb_dcd_reset_fifo(rhport, i, 0); musb_dcd_reset_fifo(rhport, i, 1); } - dcd_event_bus_reset(rhport, (ctrl_regs->POWER & USB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); + dcd_event_bus_reset(rhport, (musb_regs->power & USB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); } /*------------------------------------------------------------------ @@ -467,8 +469,8 @@ static void process_bus_reset(uint8_t rhport) void dcd_init(uint8_t rhport) { - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); - ctrl_regs->IE |= USB_IE_SUSPND; + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_regs->intrusben |= USB_IE_SUSPND; musb_dcd_int_clear(rhport); musb_dcd_phy_init(rhport); dcd_connect(rhport); @@ -497,30 +499,29 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) } // Wake up host -void dcd_remote_wakeup(uint8_t rhport) -{ - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); - ctrl_regs->POWER |= USB_POWER_RESUME; +void dcd_remote_wakeup(uint8_t rhport) { + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_regs->power |= USB_POWER_RESUME; unsigned cnt = SystemCoreClock / 1000; while (cnt--) __NOP(); - ctrl_regs->POWER &= ~USB_POWER_RESUME; + musb_regs->power &= ~USB_POWER_RESUME; } // Connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); - ctrl_regs->POWER |= TUD_OPT_HIGH_SPEED ? USB_POWER_HSENAB : 0; - ctrl_regs->POWER |= USB_POWER_SOFTCONN; + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_regs->power |= TUD_OPT_HIGH_SPEED ? USB_POWER_HSENAB : 0; + musb_regs->power |= USB_POWER_SOFTCONN; } // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); - ctrl_regs->POWER &= ~USB_POWER_SOFTCONN; + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_regs->power &= ~USB_POWER_SOFTCONN; } void dcd_sof_enable(uint8_t rhport, bool en) @@ -552,23 +553,25 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) pipe->remaining = 0; volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + musb_regs_t* musb_regs = MUSB_REGS(rhport); if (dir_in) { regs->TXMAXP = mps; regs->TXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0; - if (regs->TXCSRL & USB_TXCSRL1_TXRDY) + if (regs->TXCSRL & USB_TXCSRL1_TXRDY) { regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; - else + } else { regs->TXCSRL = USB_TXCSRL1_CLRDT; - ctrl_regs->TXIE |= TU_BIT(epn); + } + musb_regs->intr_txen |= TU_BIT(epn); } else { regs->RXMAXP = mps; regs->RXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; - if (regs->RXCSRL & USB_RXCSRL1_RXRDY) + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) { regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; - else + } else { regs->RXCSRL = USB_RXCSRL1_CLRDT; - ctrl_regs->RXIE |= TU_BIT(epn); + } + musb_regs->intr_rxen |= TU_BIT(epn); } /* Setup FIFO */ @@ -580,11 +583,11 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) void dcd_edpt_close_all(uint8_t rhport) { volatile musb_epn_regs_t *regs; - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + musb_regs_t* musb_regs = MUSB_REGS(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); - ctrl_regs->TXIE = 1; /* Enable only EP0 */ - ctrl_regs->RXIE = 0; + musb_regs->intr_txen = 1; /* Enable only EP0 */ + musb_regs->intr_rxen = 0; for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { regs = musb_dcd_epn_regs(rhport, i); regs->TXMAXP = 0; @@ -596,10 +599,11 @@ void dcd_edpt_close_all(uint8_t rhport) regs->RXMAXP = 0; regs->RXCSRH = 0; - if (regs->RXCSRL & USB_RXCSRL1_RXRDY) + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) { regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; - else + } else { regs->RXCSRL = USB_RXCSRL1_CLRDT; + } musb_dcd_reset_fifo(rhport, i, 0); musb_dcd_reset_fifo(rhport, i, 1); @@ -614,25 +618,27 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) unsigned const dir_in = tu_edpt_dir(ep_addr); volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + musb_regs_t* musb_regs = MUSB_REGS(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (dir_in) { - ctrl_regs->TXIE &= ~TU_BIT(epn); + musb_regs->intr_txen &= ~TU_BIT(epn); regs->TXMAXP = 0; regs->TXCSRH = 0; - if (regs->TXCSRL & USB_TXCSRL1_TXRDY) + if (regs->TXCSRL & USB_TXCSRL1_TXRDY) { regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; - else + } else { regs->TXCSRL = USB_TXCSRL1_CLRDT; + } } else { - ctrl_regs->RXIE &= ~TU_BIT(epn); + musb_regs->intr_rxen &= ~TU_BIT(epn); regs->RXMAXP = 0; regs->RXCSRH = 0; - if (regs->RXCSRL & USB_RXCSRL1_RXRDY) + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) { regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; - else + } else { regs->RXCSRL = USB_RXCSRL1_CLRDT; + } } musb_dcd_reset_fifo(rhport, epn, dir_in); if (ie) musb_dcd_int_enable(rhport); @@ -650,8 +656,9 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t if (epnum) { _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); - } else + } else { ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); + } if (ie) musb_dcd_int_enable(rhport); return ret; } @@ -719,18 +726,18 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) void dcd_int_handler(uint8_t rhport) { uint_fast8_t is, txis, rxis; - volatile musb_ctl_regs_t *ctrl_regs; //Part specific ISR setup/entry musb_dcd_int_handler_enter(rhport); - ctrl_regs = musb_dcd_ctl_regs(rhport); - is = ctrl_regs->IS; /* read and clear interrupt status */ - txis = ctrl_regs->TXIS; /* read and clear interrupt status */ - rxis = ctrl_regs->RXIS; /* read and clear interrupt status */ + musb_regs_t* musb_regs = MUSB_REGS(rhport); + + is = musb_regs->intrusb; /* read and clear interrupt status */ + txis = musb_regs->intr_tx; /* read and clear interrupt status */ + rxis = musb_regs->intr_rx; /* read and clear interrupt status */ // TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis); - is &= ctrl_regs->IE; /* Clear disabled interrupts */ + is &= musb_regs->intrusben; /* Clear disabled interrupts */ if (is & USB_IS_DISCON) { } if (is & USB_IS_SOF) { @@ -746,7 +753,7 @@ void dcd_int_handler(uint8_t rhport) dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } - txis &= ctrl_regs->TXIE; /* Clear disabled interrupts */ + txis &= musb_regs->intr_txen; /* Clear disabled interrupts */ if (txis & USB_TXIE_EP0) { process_ep0(rhport); txis &= ~TU_BIT(0); @@ -756,7 +763,7 @@ void dcd_int_handler(uint8_t rhport) process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN)); txis &= ~TU_BIT(num); } - rxis &= ctrl_regs->RXIE; /* Clear disabled interrupts */ + rxis &= musb_regs->intr_rxen; /* Clear disabled interrupts */ while (rxis) { unsigned const num = __builtin_ctz(rxis); process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT)); diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 0712aeda4..9c048513c 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -28,12 +28,14 @@ #define TUSB_MUSB_MAX32_H_ #ifdef __cplusplus - extern "C" { +extern "C" { #endif #include "mxc_device.h" #include "usbhs_regs.h" +const uintptr_t MUSB_BASES[] = { MXC_BASE_USBHS }; + #if CFG_TUD_ENABLED #define USBHS_M31_CLOCK_RECOVERY @@ -92,14 +94,12 @@ static inline void musb_dcd_int_handler_enter(uint8_t rhport) { } } -static inline void musb_dcd_int_handler_exit(uint8_t rhport) -{ +static inline void musb_dcd_int_handler_exit(uint8_t rhport) { //restore register index musb_periph_inst[rhport]->index = isr_saved_index; } -static inline void musb_dcd_phy_init(uint8_t rhport) -{ +static inline void musb_dcd_phy_init(uint8_t rhport) { //Interrupt for VBUS disconnect musb_periph_inst[rhport]->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS; @@ -136,42 +136,32 @@ static inline void musb_dcd_phy_init(uint8_t rhport) musb_periph_inst[rhport]->m31_phy_ponrst = 1; } -static inline volatile musb_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) -{ - volatile musb_ctl_regs_t *regs = (volatile musb_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->faddr)); - return regs; -} - -static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) -{ +static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) { //Need to set index to map EP registers musb_periph_inst[rhport]->index = epnum; - volatile musb_epn_regs_t *regs = (volatile musb_epn_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->inmaxp)); + volatile musb_epn_regs_t* regs = (volatile musb_epn_regs_t*) ((uintptr_t) &(musb_periph_inst[rhport]->inmaxp)); return regs; } -static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) -{ +static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) { //Need to set index to map EP0 registers musb_periph_inst[rhport]->index = 0; - volatile musb_ep0_regs_t *regs = (volatile musb_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->csr0)); + volatile musb_ep0_regs_t* regs = (volatile musb_ep0_regs_t*) ((uintptr_t) &(musb_periph_inst[rhport]->csr0)); return regs; } -static volatile void *musb_dcd_ep_get_fifo_ptr(uint8_t rhport, unsigned epnum) -{ - volatile uint32_t *ptr; +static volatile void* musb_dcd_ep_get_fifo_ptr(uint8_t rhport, unsigned epnum) { + volatile uint32_t* ptr; ptr = &(musb_periph_inst[rhport]->fifo0); ptr += epnum; - return (volatile void *) ptr; + return (volatile void*) ptr; } -static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) -{ - (void)mps; +static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { + (void) mps; //Most likely the caller has already grabbed the right register block. But //as a precaution save and restore the register bank anyways @@ -180,7 +170,7 @@ static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned musb_periph_inst[rhport]->index = epnum; //Disable double buffering - if(dir_in) { + if (dir_in) { musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE); } else { musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); @@ -189,8 +179,7 @@ static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned musb_periph_inst[rhport]->index = saved_index; } -static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in) -{ +static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in) { //Most likely the caller has already grabbed the right register block. But //as a precaution save and restore the register bank anyways unsigned saved_index = musb_periph_inst[rhport]->index; @@ -198,7 +187,7 @@ static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned musb_periph_inst[rhport]->index = epnum; //Disable double buffering - if(dir_in) { + if (dir_in) { musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS); } else { musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); @@ -210,7 +199,7 @@ static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned #endif // CFG_TUD_ENABLED #ifdef __cplusplus - } +} #endif #endif // TUSB_MUSB_MAX32_H_ diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index ec0a267b1..df77303a0 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -42,6 +42,8 @@ #error "Unsupported MCUs" #endif +const uintptr_t MUSB_BASES[] = { USB0_BASE }; + // Header supports both device and host modes. Only include what's necessary #if CFG_TUD_ENABLED @@ -95,12 +97,6 @@ static inline void musb_dcd_int_handler_exit(uint8_t rhport){ //Nothing to do for this part } -static inline volatile musb_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) -{ - volatile musb_ctl_regs_t *regs = (volatile musb_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->FADDR)); - return regs; -} - static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) { uintptr_t baseptr = (uintptr_t)&(musb_periph_inst[rhport]->TXMAXP1); diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index d21dcd6da..9986a30e0 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -32,8 +32,8 @@ * *******************************************************************************/ -#ifndef _TUSB_MUSB_TYPE_H_ -#define _TUSB_MUSB_TYPE_H_ +#ifndef TUSB_MUSB_TYPE_H_ +#define TUSB_MUSB_TYPE_H_ #include "stdint.h" @@ -41,6 +41,22 @@ extern "C" { #endif +#ifndef __IO + #define __IO volatile +#endif + +#ifndef __I + #define __I volatile const +#endif + +#ifndef __O + #define __O volatile +#endif + +#ifndef __R + #define __R volatile const +#endif + // Endpoint register mapping. Non-zero end points. typedef struct TU_ATTR_PACKED { uint16_t TXMAXP; @@ -60,17 +76,131 @@ typedef struct TU_ATTR_PACKED { uint8_t COUNT0; } musb_ep0_regs_t; -// Control register mapping -typedef struct TU_ATTR_PACKED { - uint8_t FADDR; - uint8_t POWER; - uint16_t TXIS; - uint16_t RXIS; - uint16_t TXIE; - uint16_t RXIE; - uint8_t IS; - uint8_t IE; -} musb_ctl_regs_t; +typedef struct { + //------------- Common -------------// + __IO uint8_t faddr; // 0x00: FADDR + __IO uint8_t power; // 0x01: POWER + + __IO uint16_t intr_tx; // 0x02: INTR_TX + __IO uint16_t intr_rx; // 0x04: INTR_RX + + __IO uint16_t intr_txen; // 0x06: INTR_TXEN + __IO uint16_t intr_rxen; // 0x08: INTR_RXEN + + __IO uint8_t intrusb; // 0x0A: INTRUSB + __IO uint8_t intrusben; // 0x0B: INTRUSBEN + + __IO uint16_t frame; // 0x0C: FRAME + __IO uint8_t index; // 0x0E: INDEX + __IO uint8_t testmode; // 0x0F: TESTMODE + __IO uint16_t inmaxp; // 0x10: INMAXP + union { + __IO uint8_t csr0; // 0x12: CSR0 + __IO uint8_t incsrl; // 0x12: INCSRL + }; + __IO uint8_t incsru; // 0x13: INCSRU + __IO uint16_t outmaxp; // 0x14: OUTMAXP + __IO uint8_t outcsrl; // 0x16: OUTCSRL + __IO uint8_t outcsru; // 0x17: OUTCSRU + union { + __IO uint16_t count0; // 0x18: COUNT0 + __IO uint16_t outcount; // 0x18: OUTCOUNT + }; + __R uint16_t rsv_0x1a_0x1f[3]; + __IO uint32_t fifo0; // 0x20: FIFO0 + __IO uint32_t fifo1; // 0x24: FIFO1 + __IO uint32_t fifo2; // 0x28: FIFO2 + __IO uint32_t fifo3; // 0x2c: FIFO3 + __IO uint32_t fifo4; // 0x30: FIFO4 + __IO uint32_t fifo5; // 0x34: FIFO5 + __IO uint32_t fifo6; // 0x38: FIFO6 + __IO uint32_t fifo7; // 0x3c: FIFO7 + __IO uint32_t fifo8; // 0x40: FIFO8 + __IO uint32_t fifo9; // 0x44: FIFO9 + __IO uint32_t fifo10; // 0x48: FIFO10 + __IO uint32_t fifo11; // 0x4c: FIFO11 + __IO uint32_t fifo12; // 0x50: FIFO12 + __IO uint32_t fifo13; // 0x54: FIFO13 + __IO uint32_t fifo14; // 0x58: FIFO14 + __IO uint32_t fifo15; // 0x5c: FIFO15 + __IO uint8_t devctl; // 0x60: DEVCTL + __IO uint8_t misc; // 0x61: MISC + + //------------- Dynammic FIFO -------------// + __IO uint8_t txfifo_sz; // 0x62: TXFIFO_SZ + __IO uint8_t rxfifo_sz; // 0x63: RXFIFO_SZ + __IO uint16_t txfifo_addr; // 0x64: TXFIFO_ADDR + __IO uint16_t rxfifo_addr; // 0x66: RXFIFO_ADDR + + //------------- Additional Control/Status -------------// + union { + __O uint32_t vcontrol; // 0x68: VCONTROL + __IO uint32_t vstatus; // 0x68: VSTATUS + }; + __IO uint16_t hwvers; // 0x6c: HWVERS + __R uint16_t rsv_0x6e_0x77[5]; + + //------------- Additional Configuration -------------// + __IO uint8_t epinfo; // 0x78: EPINFO + __IO uint8_t raminfo; // 0x79: RAMINFO + __IO uint8_t softreset; // 0x7A: SOFTRESET (Analog), Link info + __IO uint8_t vplen; // 0x7B: VPLEN + __IO uint8_t hs_eof1; // 0x7C: HS_EOF1 + __IO uint8_t fs_eof1; // 0x7D: FS_EOF1 + __IO uint8_t ls_eof1; // 0x7E: LS_EOF1 + __IO uint8_t soft_rst; // 0x7F: SOFT_RST + + //------------- Extended -------------// + __IO uint16_t ctuch; // 0x80: CTUCH + __IO uint16_t cthsrtn; // 0x82: CTHSRTN + __R uint32_t rsv_0x84_0x3ff[223]; + + //------------- Analog PHY -------------// + __IO uint32_t mxm_usb_reg_00; // 0x400: MXM_USB_REG_00 + __IO uint32_t m31_phy_utmi_reset; // 0x404: M31_PHY_UTMI_RESET + __IO uint32_t m31_phy_utmi_vcontrol; // 0x408: M31_PHY_UTMI_VCONTROL + __IO uint32_t m31_phy_clk_en; // 0x40C: M31_PHY_CLK_EN + __IO uint32_t m31_phy_ponrst; // 0x410: M31_PHY_PONRST + __IO uint32_t m31_phy_noncry_rstb; // 0x414: M31_PHY_NONCRY_RSTB + __IO uint32_t m31_phy_noncry_en; // 0x418: M31_PHY_NONCRY_EN + __R uint32_t rsv_0x41c; + __IO uint32_t m31_phy_u2_compliance_en; // 0x420: M31_PHY_U2_COMPLIANCE_EN + __IO uint32_t m31_phy_u2_compliance_dac_adj; // 0x424: M31_PHY_U2_COMPLIANCE_DAC_ADJ + __IO uint32_t m31_phy_u2_compliance_dac_adj_en; // 0x428: M31_PHY_U2_COMPLIANCE_DAC_ADJ_EN + __IO uint32_t m31_phy_clk_rdy; // 0x42C: M31_PHY_CLK_RDY + __IO uint32_t m31_phy_pll_en; // 0x430: M31_PHY_PLL_EN + __IO uint32_t m31_phy_bist_ok; // 0x434: M31_PHY_BIST_OK + __IO uint32_t m31_phy_data_oe; // 0x438: M31_PHY_DATA_OE + __IO uint32_t m31_phy_oscouten; // 0x43C: M31_PHY_OSCOUTEN + __IO uint32_t m31_phy_lpm_alive; // 0x440: M31_PHY_LPM_ALIVE + __IO uint32_t m31_phy_hs_bist_mode; // 0x444: M31_PHY_HS_BIST_MODE + __IO uint32_t m31_phy_coreclkin; // 0x448: M31_PHY_CORECLKIN + __IO uint32_t m31_phy_xtlsel; // 0x44C: M31_PHY_XTLSEL + __IO uint32_t m31_phy_ls_en; // 0x450: M31_PHY_LS_EN + __IO uint32_t m31_phy_debug_sel; // 0x454: M31_PHY_DEBUG_SEL + __IO uint32_t m31_phy_debug_out; // 0x458: M31_PHY_DEBUG_OUT + __IO uint32_t m31_phy_outclksel; // 0x45C: M31_PHY_OUTCLKSEL + __IO uint32_t m31_phy_xcfgi_31_0; // 0x460: M31_PHY_XCFGI_31_0 + __IO uint32_t m31_phy_xcfgi_63_32; // 0x464: M31_PHY_XCFGI_63_32 + __IO uint32_t m31_phy_xcfgi_95_64; // 0x468: M31_PHY_XCFGI_95_64 + __IO uint32_t m31_phy_xcfgi_127_96; // 0x46C: M31_PHY_XCFGI_127_96 + __IO uint32_t m31_phy_xcfgi_137_128; // 0x470: M31_PHY_XCFGI_137_128 + __IO uint32_t m31_phy_xcfg_hs_coarse_tune_num; // 0x474: M31_PHY_XCFG_HS_COARSE_TUNE_NUM + __IO uint32_t m31_phy_xcfg_hs_fine_tune_num; // 0x478: M31_PHY_XCFG_HS_FINE_TUNE_NUM + __IO uint32_t m31_phy_xcfg_fs_coarse_tune_num; // 0x47C: M31_PHY_XCFG_FS_COARSE_TUNE_NUM + __IO uint32_t m31_phy_xcfg_fs_fine_tune_num; // 0x480: M31_PHY_XCFG_FS_FINE_TUNE_NUM + __IO uint32_t m31_phy_xcfg_lock_range_max; // 0x484: M31_PHY_XCFG_LOCK_RANGE_MAX + __IO uint32_t m31_phy_xcfgi_lock_range_min; // 0x488: M31_PHY_XCFGI_LOCK_RANGE_MIN + __IO uint32_t m31_phy_xcfg_ob_rsel; // 0x48C: M31_PHY_XCFG_OB_RSEL + __IO uint32_t m31_phy_xcfg_oc_rsel; // 0x490: M31_PHY_XCFG_OC_RSEL + __IO uint32_t m31_phy_xcfgo; // 0x494: M31_PHY_XCFGO + __IO uint32_t mxm_int; // 0x498: MXM_INT + __IO uint32_t mxm_int_en; // 0x49C: MXM_INT_EN + __IO uint32_t mxm_suspend; // 0x4A0: MXM_SUSPEND + __IO uint32_t mxm_reg_a4; // 0x4A4: MXM_REG_A4 +} musb_regs_t; + +TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x4A8, "size is not correct"); //***************************************************************************** // -- cgit v1.3.1 From 7d8d364332189f840cbd0265f2834c1b343c5e52 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Aug 2024 16:52:50 +0700 Subject: update musb fifo usage --- src/portable/mentor/musb/dcd_musb.c | 20 +++++++++++--------- src/portable/mentor/musb/musb_max32.h | 10 ---------- src/portable/mentor/musb/musb_ti.h | 10 ---------- src/portable/mentor/musb/musb_type.h | 17 +---------------- 4 files changed, 12 insertions(+), 45 deletions(-) diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 78fc3d616..114720a6a 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -153,10 +153,10 @@ static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigne ops[dir].tu_fifo_advance(f, total_len - rem); } -static void process_setup_packet(uint8_t rhport) -{ +static void process_setup_packet(uint8_t rhport) { + musb_regs_t* musb_regs = MUSB_REGS(rhport); uint32_t *p = (void*)&_dcd.setup_packet; - volatile uint32_t *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, 0); + volatile uint32_t *fifo_ptr = &musb_regs->fifo[0]; volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); p[0] = *fifo_ptr; p[1] = *fifo_ptr; @@ -185,11 +185,12 @@ static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) return true; } + musb_regs_t* musb_regs = MUSB_REGS(rhport); volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); const unsigned mps = regs->TXMAXP; const unsigned len = TU_MIN(mps, rem); void *buf = pipe->buf; - volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, epnum); + volatile void *fifo_ptr = &musb_regs->fifo[epnum]; // TU_LOG1(" %p mps %d len %d rem %d\r\n", buf, mps, len, rem); if (len) { if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { @@ -210,6 +211,7 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) unsigned epnum = tu_edpt_number(ep_addr); unsigned epnum_minus1 = epnum - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + musb_regs_t* musb_regs = MUSB_REGS(rhport); volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, regs->RXCSRL); @@ -220,7 +222,7 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) const unsigned vld = regs->RXCOUNT; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); void *buf = pipe->buf; - volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, epnum); + volatile void *fifo_ptr = &musb_regs->fifo[epnum]; if (len) { if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_OUT); @@ -262,6 +264,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ { (void)rhport; TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ + musb_regs_t* musb_regs = MUSB_REGS(rhport); volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); const unsigned req = _dcd.setup_packet.bmRequestType; TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); @@ -289,7 +292,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ TU_ASSERT(total_bytes <= _dcd.remaining_ctrl); const unsigned rem = _dcd.remaining_ctrl; const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes); - volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, 0); + volatile void *fifo_ptr = &musb_regs->fifo[0]; if (dir_in) { pipe_write_packet(buffer, fifo_ptr, len); @@ -327,6 +330,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ static void process_ep0(uint8_t rhport) { + musb_regs_t* musb_regs = MUSB_REGS(rhport); volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); uint_fast8_t csrl = ep0_regs->CSRL0; @@ -368,7 +372,7 @@ static void process_ep0(uint8_t rhport) const unsigned vld = ep0_regs->COUNT0; const unsigned rem = _dcd.pipe0.remaining; const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); - volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, 0); + volatile void *fifo_ptr = &musb_regs->fifo[0]; pipe_read_packet(_dcd.pipe0.buf, fifo_ptr, len); _dcd.pipe0.remaining = rem - len; @@ -383,8 +387,6 @@ static void process_ep0(uint8_t rhport) return; } - musb_regs_t* musb_regs = MUSB_REGS(rhport); - /* When CSRL0 is zero, it means that completion of sending a any length packet * or receiving a zero length packet. */ if (req != REQUEST_TYPE_INVALID && !tu_edpt_dir(req)) { diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 9c048513c..0a97f529a 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -150,16 +150,6 @@ static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) { return regs; } -static volatile void* musb_dcd_ep_get_fifo_ptr(uint8_t rhport, unsigned epnum) { - volatile uint32_t* ptr; - - ptr = &(musb_periph_inst[rhport]->fifo0); - ptr += epnum; - - return (volatile void*) ptr; -} - - static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { (void) mps; diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index df77303a0..499e01e63 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -113,16 +113,6 @@ static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) return regs; } -static volatile void *musb_dcd_ep_get_fifo_ptr(uint8_t rhport, unsigned epnum) -{ - if(epnum){ - return (volatile void *)(&(musb_periph_inst[rhport]->FIFO1_WORD) + (epnum - 1)); - } else { - return (volatile void *)&(musb_periph_inst[rhport]->FIFO0_WORD); - } -} - - typedef struct { uint_fast16_t beg; /* offset of including first element */ uint_fast16_t end; /* offset of excluding the last element */ diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 9986a30e0..c31e0c984 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -107,22 +107,7 @@ typedef struct { __IO uint16_t outcount; // 0x18: OUTCOUNT }; __R uint16_t rsv_0x1a_0x1f[3]; - __IO uint32_t fifo0; // 0x20: FIFO0 - __IO uint32_t fifo1; // 0x24: FIFO1 - __IO uint32_t fifo2; // 0x28: FIFO2 - __IO uint32_t fifo3; // 0x2c: FIFO3 - __IO uint32_t fifo4; // 0x30: FIFO4 - __IO uint32_t fifo5; // 0x34: FIFO5 - __IO uint32_t fifo6; // 0x38: FIFO6 - __IO uint32_t fifo7; // 0x3c: FIFO7 - __IO uint32_t fifo8; // 0x40: FIFO8 - __IO uint32_t fifo9; // 0x44: FIFO9 - __IO uint32_t fifo10; // 0x48: FIFO10 - __IO uint32_t fifo11; // 0x4c: FIFO11 - __IO uint32_t fifo12; // 0x50: FIFO12 - __IO uint32_t fifo13; // 0x54: FIFO13 - __IO uint32_t fifo14; // 0x58: FIFO14 - __IO uint32_t fifo15; // 0x5c: FIFO15 + __IO uint32_t fifo[16]; // 0x20-0x5C: FIFO 0-15 __IO uint8_t devctl; // 0x60: DEVCTL __IO uint8_t misc; // 0x61: MISC -- cgit v1.3.1 From 06e52e4fb298c15c6d918150b1c70873963c0673 Mon Sep 17 00:00:00 2001 From: Hinko Kocevar Date: Thu, 15 Aug 2024 14:33:02 +0200 Subject: couple of fixes for usbtmc example --- examples/device/usbtmc/src/usb_descriptors.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/examples/device/usbtmc/src/usb_descriptors.c b/examples/device/usbtmc/src/usb_descriptors.c index 54948291e..85acd990a 100644 --- a/examples/device/usbtmc/src/usb_descriptors.c +++ b/examples/device/usbtmc/src/usb_descriptors.c @@ -38,7 +38,7 @@ #define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) -#define USB_VID 0xCafe +#define USB_VID 0xcafe #define USB_BCD 0x0200 //--------------------------------------------------------------------+ @@ -48,8 +48,8 @@ tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = 0x0200, - .bDeviceClass = 0x00, + .bcdUSB = USB_BCD, + .bDeviceClass = TUSB_CLASS_UNSPECIFIED, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, @@ -57,7 +57,7 @@ tusb_desc_device_t const desc_device = .idVendor = USB_VID, .idProduct = USB_PID, - .bcdDevice = USB_BCD, + .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, @@ -112,17 +112,6 @@ enum #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_USBTMC_DESC_LEN) -#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX - // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number - // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... - // Note: since CDC EP ( 1 & 2), HID (4) are spot-on, thus we only need to force - // endpoint number for MSC to 5 - #define EPNUM_MSC 0x05 -#else - #define EPNUM_MSC 0x03 -#endif - - uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA @@ -151,7 +140,7 @@ tusb_desc_device_qualifier_t const desc_device_qualifier = .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, - .bDeviceClass = 0x00, + .bDeviceClass = TUSB_CLASS_UNSPECIFIED, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, -- cgit v1.3.1 From 6152adb17fd0e8d76c60f589d84eee0fec323fa5 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Aug 2024 19:05:28 +0700 Subject: use musb_ep_csr_t for indexed CSR, also use indexed csr for TI access as well. Merge ep0 and epn together --- src/portable/mentor/musb/dcd_musb.c | 181 +++++++++++++++++----------------- src/portable/mentor/musb/musb_max32.h | 14 --- src/portable/mentor/musb/musb_ti.h | 16 --- src/portable/mentor/musb/musb_type.h | 104 +++++++++++++------ 4 files changed, 163 insertions(+), 152 deletions(-) diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 114720a6a..48f6e9d97 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -41,10 +41,6 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); // Following symbols must be defined by port header // - musb_dcd_int_enable/disable/clear/get_enable // - musb_dcd_int_handler_enter/exit -// - musb_dcd_epn_regs: Get memory mapped struct of end point registers -// - musb_dcd_ep0_regs: Get memory mapped struct of EP0 registers -// - musb_dcd_ctl_regs: Get memory mapped struct of control registers -// - musb_dcd_ep_get_fifo_ptr: Gets the address of the provided EP's FIFO // - musb_dcd_setup_fifo/reset_fifo: Configuration of the EP's FIFO #if TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) #include "musb_ti.h" @@ -157,7 +153,7 @@ static void process_setup_packet(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); uint32_t *p = (void*)&_dcd.setup_packet; volatile uint32_t *fifo_ptr = &musb_regs->fifo[0]; - volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + p[0] = *fifo_ptr; p[1] = *fifo_ptr; @@ -170,7 +166,10 @@ static void process_setup_packet(uint8_t rhport) { _dcd.remaining_ctrl = len; const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); /* Clear RX FIFO and reverse the transaction direction */ - if (len && dir_in) ep0_regs->CSRL0 = USB_CSRL0_RXRDYC; + if (len && dir_in) { + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0); + ep_csr->csr0l = USB_CSRL0_RXRDYC; + } } static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) @@ -186,8 +185,8 @@ static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) } musb_regs_t* musb_regs = MUSB_REGS(rhport); - volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); - const unsigned mps = regs->TXMAXP; + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); + const unsigned mps = ep_csr->tx_maxp; const unsigned len = TU_MIN(mps, rem); void *buf = pipe->buf; volatile void *fifo_ptr = &musb_regs->fifo[epnum]; @@ -201,8 +200,8 @@ static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) } pipe->remaining = rem - len; } - regs->TXCSRL = USB_TXCSRL1_TXRDY; - // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum, regs->TXCSRL, rem - len); + ep_csr->tx_csrl = USB_TXCSRL1_TXRDY; + // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum, ep_csr->tx_csrl, rem - len); return false; } @@ -212,14 +211,14 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) unsigned epnum_minus1 = epnum - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; musb_regs_t* musb_regs = MUSB_REGS(rhport); - volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); - // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, regs->RXCSRL); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); + // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, ep_csr->rx_csrl); - TU_ASSERT(regs->RXCSRL & USB_RXCSRL1_RXRDY); + TU_ASSERT(ep_csr->rx_csrl & USB_RXCSRL1_RXRDY); - const unsigned mps = regs->RXMAXP; + const unsigned mps = ep_csr->rx_maxp; const unsigned rem = pipe->remaining; - const unsigned vld = regs->RXCOUNT; + const unsigned vld = ep_csr->rx_count; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); void *buf = pipe->buf; volatile void *fifo_ptr = &musb_regs->fifo[epnum]; @@ -236,7 +235,7 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) pipe->buf = NULL; return NULL != buf; } - regs->RXCSRL = 0; /* Clear RXRDY bit */ + ep_csr->rx_csrl = 0; /* Clear RXRDY bit */ return false; } @@ -254,8 +253,9 @@ static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16 if (dir_in) { handle_xfer_in(rhport, ep_addr); } else { - volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); - if (regs->RXCSRL & USB_RXCSRL1_RXRDY) regs->RXCSRL = 0; + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); + if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) ep_csr->rx_csrl = 0; } return true; } @@ -265,7 +265,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ (void)rhport; TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ musb_regs_t* musb_regs = MUSB_REGS(rhport); - volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0); const unsigned req = _dcd.setup_packet.bmRequestType; TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); @@ -276,7 +276,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ * may have already finished and received the next setup packet * without calling this function, so we have no choice but to * invoke the callback function of status packet here. */ - // TU_LOG1(" STATUS OUT ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); + // TU_LOG1(" STATUS OUT ep_csr->csr0l = %x\r\n", ep_csr->csr0l); _dcd.status_out = 0; if (req == REQUEST_TYPE_INVALID) { dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); @@ -305,25 +305,25 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ _dcd.status_out = 1; /* Flush TX FIFO and reverse the transaction direction. */ - ep0_regs->CSRL0 = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND; + ep_csr->csr0l = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND; } else { - ep0_regs->CSRL0 = USB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ + ep_csr->csr0l = USB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ } - // TU_LOG1(" IN ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); + // TU_LOG1(" IN ep_csr->csr0l = %x\r\n", ep_csr->csr0l); } else { - // TU_LOG1(" OUT ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); + // TU_LOG1(" OUT ep_csr->csr0l = %x\r\n", ep_csr->csr0l); _dcd.pipe0.buf = buffer; _dcd.pipe0.length = len; _dcd.pipe0.remaining = len; - ep0_regs->CSRL0 = USB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ + ep_csr->csr0l = USB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ } } else if (dir_in) { - // TU_LOG1(" STATUS IN ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); + // TU_LOG1(" STATUS IN ep_csr->csr0l = %x\r\n", ep_csr->csr0l); _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO and reverse the transaction direction */ - ep0_regs->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; + ep_csr->csr0l = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; } return true; } @@ -331,21 +331,21 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ static void process_ep0(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); - volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); - uint_fast8_t csrl = ep0_regs->CSRL0; + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0); + uint_fast8_t csrl = ep_csr->csr0l; - // TU_LOG1(" EP0 ep0_regs->CSRL0 = %x\r\n", csrl); + // TU_LOG1(" EP0 ep_csr->csr0l = %x\r\n", csrl); if (csrl & USB_CSRL0_STALLED) { /* Returned STALL packet to HOST. */ - ep0_regs->CSRL0 = 0; /* Clear STALL */ + ep_csr->csr0l = 0; /* Clear STALL */ return; } unsigned req = _dcd.setup_packet.bmRequestType; if (csrl & USB_CSRL0_SETEND) { TU_LOG1(" ABORT by the next packets\r\n"); - ep0_regs->CSRL0 = USB_CSRL0_SETENDC; + ep_csr->csr0l = USB_CSRL0_SETENDC; if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { /* DATA stage was aborted by receiving STATUS or SETUP packet. */ _dcd.pipe0.buf = NULL; @@ -363,13 +363,13 @@ static void process_ep0(uint8_t rhport) /* Received SETUP or DATA OUT packet */ if (req == REQUEST_TYPE_INVALID) { /* SETUP */ - TU_ASSERT(sizeof(tusb_control_request_t) == ep0_regs->COUNT0,); + TU_ASSERT(sizeof(tusb_control_request_t) == ep_csr->rx_count,); process_setup_packet(rhport); return; } if (_dcd.pipe0.buf) { /* DATA OUT */ - const unsigned vld = ep0_regs->COUNT0; + const unsigned vld = ep_csr->rx_count; const unsigned rem = _dcd.pipe0.remaining; const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); volatile void *fifo_ptr = &musb_regs->fifo[0]; @@ -415,22 +415,23 @@ static void process_ep0(uint8_t rhport) static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) { bool completed; - const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned epn = tu_edpt_number(ep_addr); const unsigned epn_minus1 = epn - 1; - volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); if (dir_in) { - // TU_LOG1(" TXCSRL%d = %x\r\n", epn, regs->TXCSRL); - if (regs->TXCSRL & USB_TXCSRL1_STALLED) { - regs->TXCSRL &= ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_UNDRN); + // TU_LOG1(" TX CSRL%d = %x\r\n", epn, ep_csr->tx_csrl); + if (ep_csr->tx_csrl & USB_TXCSRL1_STALLED) { + ep_csr->tx_csrl &= ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_UNDRN); return; } completed = handle_xfer_in(rhport, ep_addr); } else { - // TU_LOG1(" RXCSRL%d = %x\r\n", epn, regs->RXCSRL); - if (regs->RXCSRL & USB_RXCSRL1_STALLED) { - regs->RXCSRL &= ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_OVER); + // TU_LOG1(" RX CSRL%d = %x\r\n", epn, ep_csr->rx_csrl); + if (ep_csr->rx_csrl & USB_RXCSRL1_STALLED) { + ep_csr->rx_csrl &= ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_OVER); return; } completed = handle_xfer_out(rhport, ep_addr); @@ -492,12 +493,14 @@ void dcd_int_disable(uint8_t rhport) void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void)dev_addr; - volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0); + _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO to return ACK. */ - ep0_regs->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; + ep_csr->csr0l = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; } // Wake up host @@ -554,24 +557,24 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) pipe->length = 0; pipe->remaining = 0; - volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); if (dir_in) { - regs->TXMAXP = mps; - regs->TXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0; - if (regs->TXCSRL & USB_TXCSRL1_TXRDY) { - regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + ep_csr->tx_maxp = mps; + ep_csr->tx_csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0; + if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) { + ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; } else { - regs->TXCSRL = USB_TXCSRL1_CLRDT; + ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; } musb_regs->intr_txen |= TU_BIT(epn); } else { - regs->RXMAXP = mps; - regs->RXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; - if (regs->RXCSRL & USB_RXCSRL1_RXRDY) { - regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + ep_csr->rx_maxp = mps; + ep_csr->rx_csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; + if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) { + ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; } else { - regs->RXCSRL = USB_RXCSRL1_CLRDT; + ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; } musb_regs->intr_rxen |= TU_BIT(epn); } @@ -584,27 +587,26 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) void dcd_edpt_close_all(uint8_t rhport) { - volatile musb_epn_regs_t *regs; musb_regs_t* musb_regs = MUSB_REGS(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); musb_regs->intr_txen = 1; /* Enable only EP0 */ musb_regs->intr_rxen = 0; for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - regs = musb_dcd_epn_regs(rhport, i); - regs->TXMAXP = 0; - regs->TXCSRH = 0; - if (regs->TXCSRL & USB_TXCSRL1_TXRDY) - regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, i); + ep_csr->tx_maxp = 0; + ep_csr->tx_csrh = 0; + if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) + ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; else - regs->TXCSRL = USB_TXCSRL1_CLRDT; + ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; - regs->RXMAXP = 0; - regs->RXCSRH = 0; - if (regs->RXCSRL & USB_RXCSRL1_RXRDY) { - regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + ep_csr->rx_maxp = 0; + ep_csr->rx_csrh = 0; + if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) { + ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; } else { - regs->RXCSRL = USB_RXCSRL1_CLRDT; + ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; } musb_dcd_reset_fifo(rhport, i, 0); @@ -618,28 +620,27 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { unsigned const epn = tu_edpt_number(ep_addr); unsigned const dir_in = tu_edpt_dir(ep_addr); - - volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (dir_in) { musb_regs->intr_txen &= ~TU_BIT(epn); - regs->TXMAXP = 0; - regs->TXCSRH = 0; - if (regs->TXCSRL & USB_TXCSRL1_TXRDY) { - regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + ep_csr->tx_maxp = 0; + ep_csr->tx_csrh = 0; + if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) { + ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; } else { - regs->TXCSRL = USB_TXCSRL1_CLRDT; + ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; } } else { musb_regs->intr_rxen &= ~TU_BIT(epn); - regs->RXMAXP = 0; - regs->RXCSRH = 0; - if (regs->RXCSRL & USB_RXCSRL1_RXRDY) { - regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + ep_csr->rx_maxp = 0; + ep_csr->rx_csrh = 0; + if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) { + ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; } else { - regs->RXCSRL = USB_RXCSRL1_CLRDT; + ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; } } musb_dcd_reset_fifo(rhport, epn, dir_in); @@ -682,25 +683,24 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ } // Stall endpoint -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) -{ +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { unsigned const epn = tu_edpt_number(ep_addr); unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); musb_dcd_int_disable(rhport); if (0 == epn) { - volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); if (!ep_addr) { /* Ignore EP80 */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.pipe0.buf = NULL; - ep0_regs->CSRL0 = USB_CSRL0_STALL; + ep_csr->csr0l = USB_CSRL0_STALL; } } else { - volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); if (tu_edpt_dir(ep_addr)) { /* IN */ - regs->TXCSRL = USB_TXCSRL1_STALL; + ep_csr->tx_csrl = USB_TXCSRL1_STALL; } else { /* OUT */ - TU_ASSERT(!(regs->RXCSRL & USB_RXCSRL1_RXRDY),); - regs->RXCSRL = USB_RXCSRL1_STALL; + TU_ASSERT(!(ep_csr->rx_csrl & USB_RXCSRL1_RXRDY),); + ep_csr->rx_csrl = USB_RXCSRL1_STALL; } } if (ie) musb_dcd_int_enable(rhport); @@ -711,13 +711,14 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; unsigned const epn = tu_edpt_number(ep_addr); - musb_epn_regs_t volatile *regs = musb_dcd_epn_regs(rhport, epn); + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (tu_edpt_dir(ep_addr)) { /* IN */ - regs->TXCSRL = USB_TXCSRL1_CLRDT; + ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; } else { /* OUT */ - regs->RXCSRL = USB_RXCSRL1_CLRDT; + ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; } if (ie) musb_dcd_int_enable(rhport); } diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 0a97f529a..43f56de3c 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -136,20 +136,6 @@ static inline void musb_dcd_phy_init(uint8_t rhport) { musb_periph_inst[rhport]->m31_phy_ponrst = 1; } -static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) { - //Need to set index to map EP registers - musb_periph_inst[rhport]->index = epnum; - volatile musb_epn_regs_t* regs = (volatile musb_epn_regs_t*) ((uintptr_t) &(musb_periph_inst[rhport]->inmaxp)); - return regs; -} - -static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) { - //Need to set index to map EP0 registers - musb_periph_inst[rhport]->index = 0; - volatile musb_ep0_regs_t* regs = (volatile musb_ep0_regs_t*) ((uintptr_t) &(musb_periph_inst[rhport]->csr0)); - return regs; -} - static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { (void) mps; diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index 499e01e63..d1a0aa4f9 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -97,22 +97,6 @@ static inline void musb_dcd_int_handler_exit(uint8_t rhport){ //Nothing to do for this part } -static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) -{ - uintptr_t baseptr = (uintptr_t)&(musb_periph_inst[rhport]->TXMAXP1); - - //On the TI parts, the epn registers are 16-bytes apart. The core regs defined - //by musb_dcd_epn_regs and 6 reserved/other use bytes - volatile musb_epn_regs_t *regs = (volatile musb_epn_regs_t*)(baseptr + ((epnum - 1) * 16)); - return regs; -} - -static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) -{ - volatile musb_ep0_regs_t *regs = (volatile musb_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->CSRL0)); - return regs; -} - typedef struct { uint_fast16_t beg; /* offset of including first element */ uint_fast16_t end; /* offset of excluding the last element */ diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index c31e0c984..670bc2ca1 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -1,3 +1,29 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + /****************************************************************************** * * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ @@ -57,24 +83,29 @@ #define __R volatile const #endif -// Endpoint register mapping. Non-zero end points. -typedef struct TU_ATTR_PACKED { - uint16_t TXMAXP; - uint8_t TXCSRL; - uint8_t TXCSRH; - uint16_t RXMAXP; - uint8_t RXCSRL; - uint8_t RXCSRH; - uint16_t RXCOUNT; -} musb_epn_regs_t; - -// Endpoint 0 register mapping. typedef struct TU_ATTR_PACKED { - uint8_t CSRL0; - uint8_t CSRH0; - uint32_t RESERVED; - uint8_t COUNT0; -} musb_ep0_regs_t; + __IO uint16_t tx_maxp; // 0x00: TXMAXP + union { + __IO uint8_t csr0l; // 0x02: CSR0 + __IO uint8_t tx_csrl; // 0x02: TX CSRL + }; + union { + __IO uint8_t csr0h; // 0x03: CSR0H + __IO uint8_t tx_csrh; // 0x03: TX CSRH + }; + __IO uint16_t rx_maxp; // 0x04: RX MAXP + __IO uint8_t rx_csrl; // 0x06: RX CSRL + __IO uint8_t rx_csrh; // 0x07: RX CSRH + __IO uint16_t rx_count; // 0x08: RX COUNT + __IO uint8_t tx_type; // 0x0A: TX TYPE + __IO uint8_t tx_interval; // 0x0B: TX INTERVAL + __IO uint8_t rx_type; // 0x0C: RX TYPE + __IO uint8_t rx_interval; // 0x0D: RX INTERVAL + __IO uint8_t reserved_0x0e; // 0x0E: Reserved + __IO uint8_t fifo_size; // 0x0F: FIFO_SIZE +} musb_ep_csr_t; + +TU_VERIFY_STATIC(sizeof(musb_ep_csr_t) == 16, "size is not correct"); typedef struct { //------------- Common -------------// @@ -93,21 +124,14 @@ typedef struct { __IO uint16_t frame; // 0x0C: FRAME __IO uint8_t index; // 0x0E: INDEX __IO uint8_t testmode; // 0x0F: TESTMODE - __IO uint16_t inmaxp; // 0x10: INMAXP - union { - __IO uint8_t csr0; // 0x12: CSR0 - __IO uint8_t incsrl; // 0x12: INCSRL - }; - __IO uint8_t incsru; // 0x13: INCSRU - __IO uint16_t outmaxp; // 0x14: OUTMAXP - __IO uint8_t outcsrl; // 0x16: OUTCSRL - __IO uint8_t outcsru; // 0x17: OUTCSRU - union { - __IO uint16_t count0; // 0x18: COUNT0 - __IO uint16_t outcount; // 0x18: OUTCOUNT - }; - __R uint16_t rsv_0x1a_0x1f[3]; + + //------------- Indexed CSR -------------// + musb_ep_csr_t indexed_csr; // 0x10-0x1F: Indexed CSR 0-15 + + //------------- FIFOs -------------// __IO uint32_t fifo[16]; // 0x20-0x5C: FIFO 0-15 + + // Common (2) __IO uint8_t devctl; // 0x60: DEVCTL __IO uint8_t misc; // 0x61: MISC @@ -138,7 +162,13 @@ typedef struct { //------------- Extended -------------// __IO uint16_t ctuch; // 0x80: CTUCH __IO uint16_t cthsrtn; // 0x82: CTHSRTN - __R uint32_t rsv_0x84_0x3ff[223]; + __R uint32_t rsv_0x84_0xff[31]; // 0x84-0xFF: Reserved + + //------------- Absolute CSR (used index to remap to Indexed above) -------------// + // TI tm4c can access this directly, but should use indexed_csr for portability + musb_ep_csr_t ep_csr[16]; // 0x100-0x1FF: EP0-15 CSR + + __R uint32_t rsv_0x200_0x3ff[128]; // 0x200-0x3FF: Reserved //------------- Analog PHY -------------// __IO uint32_t mxm_usb_reg_00; // 0x400: MXM_USB_REG_00 @@ -187,6 +217,16 @@ typedef struct { TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x4A8, "size is not correct"); +//--------------------------------------------------------------------+ +// Helper +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_regs, unsigned epnum) { + musb_regs->index = epnum; + return &musb_regs->indexed_csr; +} + + //***************************************************************************** // // The following are defines for the bit fields in the USB_O_FADDR register. -- cgit v1.3.1 From 33e3ea36450a30d76113e5e356ddf5f99cdda2c5 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Aug 2024 23:46:33 +0700 Subject: remove analog PHY from musb_regs_t hil: remove ch32v203 since not reliable enough --- src/portable/mentor/musb/musb_type.h | 138 ++++++++++++----------------------- test/hil/rpi.json | 14 ++-- 2 files changed, 55 insertions(+), 97 deletions(-) diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 670bc2ca1..57ab2aefa 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -97,136 +97,94 @@ typedef struct TU_ATTR_PACKED { __IO uint8_t rx_csrl; // 0x06: RX CSRL __IO uint8_t rx_csrh; // 0x07: RX CSRH __IO uint16_t rx_count; // 0x08: RX COUNT - __IO uint8_t tx_type; // 0x0A: TX TYPE + union { + __IO uint8_t type0; // 0x0A: TYPE0 (host only) + __IO uint8_t tx_type; // 0x0A: TX TYPE + }; __IO uint8_t tx_interval; // 0x0B: TX INTERVAL __IO uint8_t rx_type; // 0x0C: RX TYPE __IO uint8_t rx_interval; // 0x0D: RX INTERVAL __IO uint8_t reserved_0x0e; // 0x0E: Reserved - __IO uint8_t fifo_size; // 0x0F: FIFO_SIZE + union { + __IO uint8_t config_data; // 0x0F: CONFIG DATA + __IO uint8_t fifo_size; // 0x0F: FIFO_SIZE + }; } musb_ep_csr_t; TU_VERIFY_STATIC(sizeof(musb_ep_csr_t) == 16, "size is not correct"); typedef struct { //------------- Common -------------// - __IO uint8_t faddr; // 0x00: FADDR - __IO uint8_t power; // 0x01: POWER + __IO uint8_t faddr; // 0x00: FADDR + __IO uint8_t power; // 0x01: POWER - __IO uint16_t intr_tx; // 0x02: INTR_TX - __IO uint16_t intr_rx; // 0x04: INTR_RX + __IO uint16_t intr_tx; // 0x02: INTR_TX + __IO uint16_t intr_rx; // 0x04: INTR_RX - __IO uint16_t intr_txen; // 0x06: INTR_TXEN - __IO uint16_t intr_rxen; // 0x08: INTR_RXEN + __IO uint16_t intr_txen; // 0x06: INTR_TXEN + __IO uint16_t intr_rxen; // 0x08: INTR_RXEN - __IO uint8_t intrusb; // 0x0A: INTRUSB - __IO uint8_t intrusben; // 0x0B: INTRUSBEN + __IO uint8_t intrusb; // 0x0A: INTRUSB + __IO uint8_t intrusben; // 0x0B: INTRUSBEN - __IO uint16_t frame; // 0x0C: FRAME - __IO uint8_t index; // 0x0E: INDEX - __IO uint8_t testmode; // 0x0F: TESTMODE + __IO uint16_t frame; // 0x0C: FRAME + __IO uint8_t index; // 0x0E: INDEX + __IO uint8_t testmode; // 0x0F: TESTMODE - //------------- Indexed CSR -------------// - musb_ep_csr_t indexed_csr; // 0x10-0x1F: Indexed CSR 0-15 + //------------- CSR (indexed) -------------// + musb_ep_csr_t indexed_csr; // 0x10-0x1F: Indexed CSR 0-15 //------------- FIFOs -------------// - __IO uint32_t fifo[16]; // 0x20-0x5C: FIFO 0-15 + __IO uint32_t fifo[16]; // 0x20-0x5C: FIFO 0-15 // Common (2) - __IO uint8_t devctl; // 0x60: DEVCTL - __IO uint8_t misc; // 0x61: MISC + __IO uint8_t devctl; // 0x60: DEVCTL + __IO uint8_t misc; // 0x61: MISC - //------------- Dynammic FIFO -------------// - __IO uint8_t txfifo_sz; // 0x62: TXFIFO_SZ - __IO uint8_t rxfifo_sz; // 0x63: RXFIFO_SZ - __IO uint16_t txfifo_addr; // 0x64: TXFIFO_ADDR - __IO uint16_t rxfifo_addr; // 0x66: RXFIFO_ADDR + //------------- Dynammic FIFO (indexed) -------------// + __IO uint8_t txfifo_sz; // 0x62: TXFIFO_SZ + __IO uint8_t rxfifo_sz; // 0x63: RXFIFO_SZ + __IO uint16_t txfifo_addr; // 0x64: TXFIFO_ADDR + __IO uint16_t rxfifo_addr; // 0x66: RXFIFO_ADDR //------------- Additional Control/Status -------------// union { - __O uint32_t vcontrol; // 0x68: VCONTROL - __IO uint32_t vstatus; // 0x68: VSTATUS + __O uint32_t vcontrol; // 0x68: VCONTROL + __IO uint32_t vstatus; // 0x68: VSTATUS }; - __IO uint16_t hwvers; // 0x6c: HWVERS - __R uint16_t rsv_0x6e_0x77[5]; - - //------------- Additional Configuration -------------// - __IO uint8_t epinfo; // 0x78: EPINFO - __IO uint8_t raminfo; // 0x79: RAMINFO - __IO uint8_t softreset; // 0x7A: SOFTRESET (Analog), Link info - __IO uint8_t vplen; // 0x7B: VPLEN - __IO uint8_t hs_eof1; // 0x7C: HS_EOF1 - __IO uint8_t fs_eof1; // 0x7D: FS_EOF1 - __IO uint8_t ls_eof1; // 0x7E: LS_EOF1 - __IO uint8_t soft_rst; // 0x7F: SOFT_RST + __IO uint16_t hwvers; // 0x6c: HWVERS + __R uint16_t rsv_0x6e_0x77[5]; // 0x6E-0x77: Reserved + + //------------- Additional Configuration -------------// + __IO uint8_t epinfo; // 0x78: EPINFO + __IO uint8_t raminfo; // 0x79: RAMINFO + __IO uint8_t softreset; // 0x7A: SOFTRESET (Analog), Link info + __IO uint8_t vplen; // 0x7B: VPLEN + __IO uint8_t hs_eof1; // 0x7C: HS_EOF1 + __IO uint8_t fs_eof1; // 0x7D: FS_EOF1 + __IO uint8_t ls_eof1; // 0x7E: LS_EOF1 + __IO uint8_t soft_rst; // 0x7F: SOFT_RST //------------- Extended -------------// - __IO uint16_t ctuch; // 0x80: CTUCH - __IO uint16_t cthsrtn; // 0x82: CTHSRTN - __R uint32_t rsv_0x84_0xff[31]; // 0x84-0xFF: Reserved + __IO uint16_t ctuch; // 0x80: CTUCH + __IO uint16_t cthsrtn; // 0x82: CTHSRTN + __R uint32_t rsv_0x84_0xff[31]; // 0x84-0xFF: Reserved //------------- Absolute CSR (used index to remap to Indexed above) -------------// // TI tm4c can access this directly, but should use indexed_csr for portability - musb_ep_csr_t ep_csr[16]; // 0x100-0x1FF: EP0-15 CSR - - __R uint32_t rsv_0x200_0x3ff[128]; // 0x200-0x3FF: Reserved - - //------------- Analog PHY -------------// - __IO uint32_t mxm_usb_reg_00; // 0x400: MXM_USB_REG_00 - __IO uint32_t m31_phy_utmi_reset; // 0x404: M31_PHY_UTMI_RESET - __IO uint32_t m31_phy_utmi_vcontrol; // 0x408: M31_PHY_UTMI_VCONTROL - __IO uint32_t m31_phy_clk_en; // 0x40C: M31_PHY_CLK_EN - __IO uint32_t m31_phy_ponrst; // 0x410: M31_PHY_PONRST - __IO uint32_t m31_phy_noncry_rstb; // 0x414: M31_PHY_NONCRY_RSTB - __IO uint32_t m31_phy_noncry_en; // 0x418: M31_PHY_NONCRY_EN - __R uint32_t rsv_0x41c; - __IO uint32_t m31_phy_u2_compliance_en; // 0x420: M31_PHY_U2_COMPLIANCE_EN - __IO uint32_t m31_phy_u2_compliance_dac_adj; // 0x424: M31_PHY_U2_COMPLIANCE_DAC_ADJ - __IO uint32_t m31_phy_u2_compliance_dac_adj_en; // 0x428: M31_PHY_U2_COMPLIANCE_DAC_ADJ_EN - __IO uint32_t m31_phy_clk_rdy; // 0x42C: M31_PHY_CLK_RDY - __IO uint32_t m31_phy_pll_en; // 0x430: M31_PHY_PLL_EN - __IO uint32_t m31_phy_bist_ok; // 0x434: M31_PHY_BIST_OK - __IO uint32_t m31_phy_data_oe; // 0x438: M31_PHY_DATA_OE - __IO uint32_t m31_phy_oscouten; // 0x43C: M31_PHY_OSCOUTEN - __IO uint32_t m31_phy_lpm_alive; // 0x440: M31_PHY_LPM_ALIVE - __IO uint32_t m31_phy_hs_bist_mode; // 0x444: M31_PHY_HS_BIST_MODE - __IO uint32_t m31_phy_coreclkin; // 0x448: M31_PHY_CORECLKIN - __IO uint32_t m31_phy_xtlsel; // 0x44C: M31_PHY_XTLSEL - __IO uint32_t m31_phy_ls_en; // 0x450: M31_PHY_LS_EN - __IO uint32_t m31_phy_debug_sel; // 0x454: M31_PHY_DEBUG_SEL - __IO uint32_t m31_phy_debug_out; // 0x458: M31_PHY_DEBUG_OUT - __IO uint32_t m31_phy_outclksel; // 0x45C: M31_PHY_OUTCLKSEL - __IO uint32_t m31_phy_xcfgi_31_0; // 0x460: M31_PHY_XCFGI_31_0 - __IO uint32_t m31_phy_xcfgi_63_32; // 0x464: M31_PHY_XCFGI_63_32 - __IO uint32_t m31_phy_xcfgi_95_64; // 0x468: M31_PHY_XCFGI_95_64 - __IO uint32_t m31_phy_xcfgi_127_96; // 0x46C: M31_PHY_XCFGI_127_96 - __IO uint32_t m31_phy_xcfgi_137_128; // 0x470: M31_PHY_XCFGI_137_128 - __IO uint32_t m31_phy_xcfg_hs_coarse_tune_num; // 0x474: M31_PHY_XCFG_HS_COARSE_TUNE_NUM - __IO uint32_t m31_phy_xcfg_hs_fine_tune_num; // 0x478: M31_PHY_XCFG_HS_FINE_TUNE_NUM - __IO uint32_t m31_phy_xcfg_fs_coarse_tune_num; // 0x47C: M31_PHY_XCFG_FS_COARSE_TUNE_NUM - __IO uint32_t m31_phy_xcfg_fs_fine_tune_num; // 0x480: M31_PHY_XCFG_FS_FINE_TUNE_NUM - __IO uint32_t m31_phy_xcfg_lock_range_max; // 0x484: M31_PHY_XCFG_LOCK_RANGE_MAX - __IO uint32_t m31_phy_xcfgi_lock_range_min; // 0x488: M31_PHY_XCFGI_LOCK_RANGE_MIN - __IO uint32_t m31_phy_xcfg_ob_rsel; // 0x48C: M31_PHY_XCFG_OB_RSEL - __IO uint32_t m31_phy_xcfg_oc_rsel; // 0x490: M31_PHY_XCFG_OC_RSEL - __IO uint32_t m31_phy_xcfgo; // 0x494: M31_PHY_XCFGO - __IO uint32_t mxm_int; // 0x498: MXM_INT - __IO uint32_t mxm_int_en; // 0x49C: MXM_INT_EN - __IO uint32_t mxm_suspend; // 0x4A0: MXM_SUSPEND - __IO uint32_t mxm_reg_a4; // 0x4A4: MXM_REG_A4 + musb_ep_csr_t ep_csr[16]; // 0x100-0x1FF: EP0-15 CSR } musb_regs_t; -TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x4A8, "size is not correct"); +TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x200, "size is not correct"); //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ - TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_regs, unsigned epnum) { musb_regs->index = epnum; return &musb_regs->indexed_csr; } - //***************************************************************************** // // The following are defines for the bit fields in the USB_O_FADDR register. diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 688ea3822..b7d36c543 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -50,13 +50,6 @@ "flasher": "openocd", "flasher_sn": "066FFF495087534867063844", "flasher_args": "-f interface/stlink.cfg -f target/stm32g0x.cfg" - }, - { - "name": "nanoch32v203", - "uid": "CDAB277B0FBC03E339E339E3", - "flasher": "openocd_wch", - "flasher_sn": "EBCA8F0670AF", - "flasher_args": "" } ], "boards-skip": [ @@ -68,6 +61,13 @@ "flasher_args": "-device MIMXRT1011xxx5A", "comment": "not running reliably in bulk with other boards, probably power, flashing etc .." }, + { + "name": "nanoch32v203", + "uid": "CDAB277B0FBC03E339E339E3", + "flasher": "openocd_wch", + "flasher_sn": "EBCA8F0670AF", + "flasher_args": "" + }, { "name": "espressif_s3_devkitm", "uid": "84F703C084E4", -- cgit v1.3.1 From 8e3093e06faf51ad855ce965b28edc2d066fb528 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 16 Aug 2024 08:21:20 +0700 Subject: update cmake profile --- .idea/cmake.xml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 729309ebb..e8b46d468 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -114,7 +114,6 @@ - @@ -122,11 +121,12 @@ - - + - + + + @@ -140,6 +140,9 @@ + + + \ No newline at end of file -- cgit v1.3.1 From c34d5e7a71303c91fab134606841dd62ec57eef6 Mon Sep 17 00:00:00 2001 From: dp111 <19616418+dp111@users.noreply.github.com> Date: Fri, 16 Aug 2024 21:43:41 +0100 Subject: Put break inside #if #endif --- src/common/tusb_fifo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 8a0fd4417..5f2dcabad 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -315,9 +315,8 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr, // Read data wrapped part if (wrap_bytes > 0) _ff_pull_const_addr(app_buf, ff_buf, wrap_bytes); } -#endif break; - +#endif default: break; } } -- cgit v1.3.1 From eaf9cc1beb6f5e34683debe531c7fa4d012c47b2 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 17 Aug 2024 13:31:31 +0700 Subject: more refactor to simplify musb driver --- src/common/tusb_mcu.h | 2 + src/portable/mentor/musb/dcd_musb.c | 176 +-- src/portable/mentor/musb/musb_max32.h | 66 +- src/portable/mentor/musb/musb_ti.h | 47 +- src/portable/mentor/musb/musb_type.h | 2387 +++++++++++++-------------------- 5 files changed, 1090 insertions(+), 1588 deletions(-) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 7ec3c5842..0180fc466 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -309,6 +309,7 @@ #elif TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) #define TUP_USBIP_MUSB + #define TUP_USBIP_MUSB_TI #define TUP_DCD_ENDPOINT_MAX 8 //--------------------------------------------------------------------+ @@ -474,6 +475,7 @@ //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002) #define TUP_USBIP_MUSB + #define TUP_USBIP_MUSB_ADI #define TUP_DCD_ENDPOINT_MAX 12 #define TUP_RHPORT_HIGHSPEED 1 diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 48f6e9d97..36690c952 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -41,10 +41,10 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); // Following symbols must be defined by port header // - musb_dcd_int_enable/disable/clear/get_enable // - musb_dcd_int_handler_enter/exit -// - musb_dcd_setup_fifo/reset_fifo: Configuration of the EP's FIFO -#if TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) +// - musb_dcd_setup_fifo: Configuration of the EP's FIFO +#if defined(TUP_USBIP_MUSB_TI) #include "musb_ti.h" -#elif TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002) +#elif defined(TUP_USBIP_MUSB_ADI) #include "musb_max32.h" #else #error "Unsupported MCU" @@ -52,6 +52,8 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); #define MUSB_REGS(rhport) ((musb_regs_t*) MUSB_BASES[rhport]) +#define MUSB_DEBUG 2 + /*------------------------------------------------------------------ * MACRO TYPEDEF CONSTANT ENUM DECLARATION *------------------------------------------------------------------*/ @@ -86,6 +88,18 @@ typedef struct *------------------------------------------------------------------*/ static dcd_data_t _dcd; +TU_ATTR_ALWAYS_INLINE static inline void fifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { + musb->index = epnum; + const uint8_t is_rx = 1 - dir_in; + +#if MUSB_CFG_DYNAMIC_FIFO + musb->fifo_size[is_rx] = 0; + musb->fifo_addr[is_rx] = 0; +#elif defined(TUP_USBIP_MUSB_ADI) + // Analog have custom double buffered in csrh register, disable it + musb->indexed_csr.maxp_csr[is_rx].csrh |= MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); +#endif +} static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { @@ -363,13 +377,13 @@ static void process_ep0(uint8_t rhport) /* Received SETUP or DATA OUT packet */ if (req == REQUEST_TYPE_INVALID) { /* SETUP */ - TU_ASSERT(sizeof(tusb_control_request_t) == ep_csr->rx_count,); + TU_ASSERT(sizeof(tusb_control_request_t) == ep_csr->count0,); process_setup_packet(rhport); return; } if (_dcd.pipe0.buf) { /* DATA OUT */ - const unsigned vld = ep_csr->rx_count; + const unsigned vld = ep_csr->count0; const unsigned rem = _dcd.pipe0.remaining; const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); volatile void *fifo_ptr = &musb_regs->fifo[0]; @@ -445,47 +459,70 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) } } -static void process_bus_reset(uint8_t rhport) -{ - musb_regs_t* musb_regs = MUSB_REGS(rhport); - /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), - * a control transfer state is SETUP or STATUS stage. */ +// Upon BUS RESET is detected, hardware havs already done: +// faddr = 0, index = 0, flushes all ep fifos, clears all ep csr, enabled all ep interrupts +static void process_bus_reset(uint8_t rhport) { + musb_regs_t* musb = MUSB_REGS(rhport); + /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), a control transfer state is SETUP or STATUS stage. */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.status_out = 0; /* When pipe0.buf has not NULL, DATA stage works in progress. */ _dcd.pipe0.buf = NULL; - musb_regs->intr_txen = 1; /* Enable only EP0 */ - musb_regs->intr_rxen = 0; + musb->intr_txen = 1; /* Enable only EP0 */ + musb->intr_rxen = 0; /* Clear FIFO settings */ for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - musb_dcd_reset_fifo(rhport, i, 0); - musb_dcd_reset_fifo(rhport, i, 1); + fifo_reset(musb, i, 0); + fifo_reset(musb, i, 1); } - dcd_event_bus_reset(rhport, (musb_regs->power & USB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); + dcd_event_bus_reset(rhport, (musb->power & USB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); } /*------------------------------------------------------------------ * Device API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport) -{ +#if CFG_TUSB_DEBUG >= MUSB_DEBUG +void print_musb_info(musb_regs_t* musb_regs) { + // print version, epinfo, raminfo, config_data0, fifo_size + TU_LOG1("musb version = %u.%u\r\n", musb_regs->hwvers_bit.major, musb_regs->hwvers_bit.minor); + TU_LOG1("Number of endpoints: %u TX, %u RX\r\n", musb_regs->epinfo_bit.tx_ep_num, musb_regs->epinfo_bit.rx_ep_num); + TU_LOG1("RAM Info: %u DMA Channel, %u RAM address width\r\n", musb_regs->raminfo_bit.dma_channel, musb_regs->raminfo_bit.ram_bits); + + musb_regs->index = 0; + TU_LOG1("config_data0 = 0x%x\r\n", musb_regs->indexed_csr.config_data0); + +#if MUSB_CFG_DYNAMIC_FIFO + TU_LOG1("Dynamic FIFO configuration\r\n"); +#else + for (uint8_t i=1; i <= musb_regs->epinfo_bit.tx_ep_num; i++) { + musb_regs->index = i; + TU_LOG1("FIFO %u Size: TX %u RX %u\r\n", i, musb_regs->indexed_csr.fifo_size_bit.tx, musb_regs->indexed_csr.fifo_size_bit.rx); + } +#endif +} +#endif + +void dcd_init(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); - musb_regs->intrusben |= USB_IE_SUSPND; + +#if CFG_TUSB_DEBUG >= MUSB_DEBUG + print_musb_info(musb_regs); +#endif + + musb_regs->intr_usben |= USB_IE_SUSPND; musb_dcd_int_clear(rhport); musb_dcd_phy_init(rhport); dcd_connect(rhport); } -void dcd_int_enable(uint8_t rhport) -{ +void dcd_int_enable(uint8_t rhport) { musb_dcd_int_enable(rhport); } -void dcd_int_disable(uint8_t rhport) -{ +void dcd_int_disable(uint8_t rhport) { musb_dcd_int_disable(rhport); } @@ -559,25 +596,17 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); - if (dir_in) { - ep_csr->tx_maxp = mps; - ep_csr->tx_csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0; - if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) { - ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; - } else { - ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; - } - musb_regs->intr_txen |= TU_BIT(epn); - } else { - ep_csr->rx_maxp = mps; - ep_csr->rx_csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; - if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) { - ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; - } else { - ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; - } - musb_regs->intr_rxen |= TU_BIT(epn); + + const uint8_t is_rx = 1 - dir_in; + ep_csr->maxp_csr[is_rx].maxp = mps; + ep_csr->maxp_csr[is_rx].csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; + + uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx); + if (ep_csr->maxp_csr[is_rx].csrl & MUSB_CSRL_PACKET_READY(is_rx)) { + csrl |= MUSB_CSRL_FLUSH_FIFO(is_rx); } + ep_csr->maxp_csr[is_rx].csrl = csrl; + musb_regs->intren_ep[is_rx] |= TU_BIT(epn); /* Setup FIFO */ musb_dcd_setup_fifo(rhport, epn, dir_in, mps); @@ -587,13 +616,13 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) void dcd_edpt_close_all(uint8_t rhport) { - musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_regs_t* musb = MUSB_REGS(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); - musb_regs->intr_txen = 1; /* Enable only EP0 */ - musb_regs->intr_rxen = 0; + musb->intr_txen = 1; /* Enable only EP0 */ + musb->intr_rxen = 0; for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, i); + musb_ep_csr_t* ep_csr = get_ep_csr(musb, i); ep_csr->tx_maxp = 0; ep_csr->tx_csrh = 0; if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) @@ -609,8 +638,8 @@ void dcd_edpt_close_all(uint8_t rhport) ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; } - musb_dcd_reset_fifo(rhport, i, 0); - musb_dcd_reset_fifo(rhport, i, 1); + fifo_reset(musb, i, 0); + fifo_reset(musb, i, 1); } if (ie) musb_dcd_int_enable(rhport); @@ -620,12 +649,12 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { unsigned const epn = tu_edpt_number(ep_addr); unsigned const dir_in = tu_edpt_dir(ep_addr); - musb_regs_t* musb_regs = MUSB_REGS(rhport); - musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); + musb_regs_t* musb = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (dir_in) { - musb_regs->intr_txen &= ~TU_BIT(epn); + musb->intr_txen &= ~TU_BIT(epn); ep_csr->tx_maxp = 0; ep_csr->tx_csrh = 0; if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) { @@ -634,7 +663,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; } } else { - musb_regs->intr_rxen &= ~TU_BIT(epn); + musb->intr_rxen &= ~TU_BIT(epn); ep_csr->rx_maxp = 0; ep_csr->rx_csrh = 0; if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) { @@ -643,7 +672,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; } } - musb_dcd_reset_fifo(rhport, epn, dir_in); + fifo_reset(musb, epn, dir_in); if (ie) musb_dcd_int_enable(rhport); } @@ -726,51 +755,48 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) /*------------------------------------------------------------------- * ISR *-------------------------------------------------------------------*/ -void dcd_int_handler(uint8_t rhport) -{ - uint_fast8_t is, txis, rxis; - +void dcd_int_handler(uint8_t rhport) { //Part specific ISR setup/entry musb_dcd_int_handler_enter(rhport); musb_regs_t* musb_regs = MUSB_REGS(rhport); - - is = musb_regs->intrusb; /* read and clear interrupt status */ - txis = musb_regs->intr_tx; /* read and clear interrupt status */ - rxis = musb_regs->intr_rx; /* read and clear interrupt status */ + uint_fast8_t intr_usb = musb_regs->intr_usb; // a read will clear this interrupt status + uint_fast8_t intr_tx = musb_regs->intr_tx; // a read will clear this interrupt status + uint_fast8_t intr_rx = musb_regs->intr_rx; // a read will clear this interrupt status // TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis); - is &= musb_regs->intrusben; /* Clear disabled interrupts */ - if (is & USB_IS_DISCON) { + intr_usb &= musb_regs->intr_usben; /* Clear disabled interrupts */ + if (intr_usb & USB_IS_DISCON) { } - if (is & USB_IS_SOF) { + if (intr_usb & USB_IS_SOF) { dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); } - if (is & USB_IS_RESET) { + if (intr_usb & USB_IS_RESET) { process_bus_reset(rhport); } - if (is & USB_IS_RESUME) { + if (intr_usb & USB_IS_RESUME) { dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } - if (is & USB_IS_SUSPEND) { + if (intr_usb & USB_IS_SUSPEND) { dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } - txis &= musb_regs->intr_txen; /* Clear disabled interrupts */ - if (txis & USB_TXIE_EP0) { + intr_tx &= musb_regs->intr_txen; /* Clear disabled interrupts */ + if (intr_tx & TU_BIT(0)) { process_ep0(rhport); - txis &= ~TU_BIT(0); + intr_tx &= ~TU_BIT(0); } - while (txis) { - unsigned const num = __builtin_ctz(txis); + while (intr_tx) { + unsigned const num = __builtin_ctz(intr_tx); process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN)); - txis &= ~TU_BIT(num); + intr_tx &= ~TU_BIT(num); } - rxis &= musb_regs->intr_rxen; /* Clear disabled interrupts */ - while (rxis) { - unsigned const num = __builtin_ctz(rxis); + + intr_rx &= musb_regs->intr_rxen; /* Clear disabled interrupts */ + while (intr_rx) { + unsigned const num = __builtin_ctz(intr_rx); process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT)); - rxis &= ~TU_BIT(num); + intr_rx &= ~TU_BIT(num); } //Part specific ISR exit diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 43f56de3c..73f63ee2e 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -34,6 +34,8 @@ extern "C" { #include "mxc_device.h" #include "usbhs_regs.h" +#define MUSB_CFG_DYNAMIC_FIFO 0 + const uintptr_t MUSB_BASES[] = { MXC_BASE_USBHS }; #if CFG_TUD_ENABLED @@ -100,40 +102,43 @@ static inline void musb_dcd_int_handler_exit(uint8_t rhport) { } static inline void musb_dcd_phy_init(uint8_t rhport) { - //Interrupt for VBUS disconnect - musb_periph_inst[rhport]->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS; + (void) rhport; + mxc_usbhs_regs_t* hs_phy = MXC_USBHS; + + // Interrupt for VBUS disconnect + hs_phy->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS; musb_dcd_int_clear(rhport); - //Unsuspend the MAC - musb_periph_inst[rhport]->mxm_suspend = 0; + // Unsuspend the MAC + hs_phy->mxm_suspend = 0; // Configure PHY - musb_periph_inst[rhport]->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11); - musb_periph_inst[rhport]->m31_phy_xcfgi_63_32 = 0; - musb_periph_inst[rhport]->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64); - musb_periph_inst[rhport]->m31_phy_xcfgi_127_96 = 0; + hs_phy->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11); + hs_phy->m31_phy_xcfgi_63_32 = 0; + hs_phy->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64); + hs_phy->m31_phy_xcfgi_127_96 = 0; #ifdef USBHS_M31_CLOCK_RECOVERY - musb_periph_inst[rhport]->m31_phy_noncry_rstb = 1; - musb_periph_inst[rhport]->m31_phy_noncry_en = 1; - musb_periph_inst[rhport]->m31_phy_outclksel = 0; - musb_periph_inst[rhport]->m31_phy_coreclkin = 0; - musb_periph_inst[rhport]->m31_phy_xtlsel = 2; /* Select 25 MHz clock */ + hs_phy->m31_phy_noncry_rstb = 1; + hs_phy->m31_phy_noncry_en = 1; + hs_phy->m31_phy_outclksel = 0; + hs_phy->m31_phy_coreclkin = 0; + hs_phy->m31_phy_xtlsel = 2; /* Select 25 MHz clock */ #else - musb_periph_inst[rhport]->m31_phy_noncry_rstb = 0; - musb_periph_inst[rhport]->m31_phy_noncry_en = 0; - musb_periph_inst[rhport]->m31_phy_outclksel = 1; - musb_periph_inst[rhport]->m31_phy_coreclkin = 1; - musb_periph_inst[rhport]->m31_phy_xtlsel = 3; /* Select 30 MHz clock */ + hs_phy->m31_phy_noncry_rstb = 0; + hs_phy->m31_phy_noncry_en = 0; + hs_phy->m31_phy_outclksel = 1; + hs_phy->m31_phy_coreclkin = 1; + hs_phy->m31_phy_xtlsel = 3; /* Select 30 MHz clock */ #endif - musb_periph_inst[rhport]->m31_phy_pll_en = 1; - musb_periph_inst[rhport]->m31_phy_oscouten = 1; + hs_phy->m31_phy_pll_en = 1; + hs_phy->m31_phy_oscouten = 1; /* Reset PHY */ - musb_periph_inst[rhport]->m31_phy_ponrst = 0; - musb_periph_inst[rhport]->m31_phy_ponrst = 1; + hs_phy->m31_phy_ponrst = 0; + hs_phy->m31_phy_ponrst = 1; } static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { @@ -155,23 +160,6 @@ static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned musb_periph_inst[rhport]->index = saved_index; } -static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in) { - //Most likely the caller has already grabbed the right register block. But - //as a precaution save and restore the register bank anyways - unsigned saved_index = musb_periph_inst[rhport]->index; - - musb_periph_inst[rhport]->index = epnum; - - //Disable double buffering - if (dir_in) { - musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS); - } else { - musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); - } - - musb_periph_inst[rhport]->index = saved_index; -} - #endif // CFG_TUD_ENABLED #ifdef __cplusplus diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index d1a0aa4f9..e43b3d3c0 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -42,8 +42,10 @@ #error "Unsupported MCUs" #endif -const uintptr_t MUSB_BASES[] = { USB0_BASE }; +#define MUSB_CFG_DYNAMIC_FIFO 1 +#define MUSB_CFG_DYNAMIC_FIFO_SIZE 4096 +const uintptr_t MUSB_BASES[] = { USB0_BASE }; // Header supports both device and host modes. Only include what's necessary #if CFG_TUD_ENABLED @@ -63,36 +65,28 @@ static inline void musb_dcd_phy_init(uint8_t rhport){ //Nothing to do for this part } -TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_enable(uint8_t rhport) -{ +TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_enable(uint8_t rhport) { NVIC_EnableIRQ(musb_irqs[rhport]); } -TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_disable(uint8_t rhport) -{ +TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_disable(uint8_t rhport) { NVIC_DisableIRQ(musb_irqs[rhport]); } -TU_ATTR_ALWAYS_INLINE -static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) -{ +TU_ATTR_ALWAYS_INLINE static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) { return NVIC_GetEnableIRQ(musb_irqs[rhport]); } -TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_clear(uint8_t rhport) -{ - NVIC_ClearPendingIRQ(musb_irqs[rhport]); +TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_clear(uint8_t rhport) { + NVIC_ClearPendingIRQ(musb_irqs[rhport]); } -static inline void musb_dcd_int_handler_enter(uint8_t rhport){ +static inline void musb_dcd_int_handler_enter(uint8_t rhport) { (void)rhport; //Nothing to do for this part } -static inline void musb_dcd_int_handler_exit(uint8_t rhport){ +static inline void musb_dcd_int_handler_exit(uint8_t rhport) { (void)rhport; //Nothing to do for this part } @@ -102,15 +96,13 @@ typedef struct { uint_fast16_t end; /* offset of excluding the last element */ } free_block_t; -static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) -{ +static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) { free_block_t *cur = beg; for (; cur < end && ((addr < cur->beg) || (cur->end <= addr)); ++cur) ; return cur; } -static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) -{ +static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) { free_block_t *p = find_containing_block(blks, blks + num, addr); TU_ASSERT(p != blks + num, -2); if (p->beg == addr) { @@ -150,8 +142,7 @@ static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_ } } -static inline unsigned free_block_size(free_block_t const *blk) -{ +static inline unsigned free_block_size(free_block_t const *blk) { return blk->end - blk->beg; } @@ -234,18 +225,6 @@ static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned } } -static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in) -{ - musb_periph_inst[rhport]->EPIDX = epnum; - if (dir_in) { - musb_periph_inst[rhport]->TXFIFOADD = 0; - musb_periph_inst[rhport]->TXFIFOSZ = 0; - } else { - musb_periph_inst[rhport]->RXFIFOADD = 0; - musb_periph_inst[rhport]->RXFIFOSZ = 0; - } -} - #endif // CFG_TUD_ENABLED #ifdef __cplusplus diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 57ab2aefa..ee0187270 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -83,20 +83,37 @@ #define __R volatile const #endif +// 0: TX (device IN, host OUT) +// 1: RX (device OUT, host IN) typedef struct TU_ATTR_PACKED { - __IO uint16_t tx_maxp; // 0x00: TXMAXP union { - __IO uint8_t csr0l; // 0x02: CSR0 - __IO uint8_t tx_csrl; // 0x02: TX CSRL + struct { + __IO uint16_t tx_maxp; // 0x00: TXMAXP + union { + __IO uint8_t csr0l; // 0x02: CSR0 + __IO uint8_t tx_csrl; // 0x02: TX CSRL + }; + union { + __IO uint8_t csr0h; // 0x03: CSR0H + __IO uint8_t tx_csrh; // 0x03: TX CSRH + }; + + __IO uint16_t rx_maxp; // 0x04: RX MAXP + __IO uint8_t rx_csrl; // 0x06: RX CSRL + __IO uint8_t rx_csrh; // 0x07: RX CSRH + }; + + struct { + __IO uint16_t maxp; // 0x00: MAXP + __IO uint8_t csrl; // 0x02: CSRL + __IO uint8_t csrh; // 0x03: CSRH + }maxp_csr[2]; }; + union { - __IO uint8_t csr0h; // 0x03: CSR0H - __IO uint8_t tx_csrh; // 0x03: TX CSRH + __IO uint16_t count0; // 0x08: COUNT0 + __IO uint16_t rx_count; // 0x08: RX COUNT }; - __IO uint16_t rx_maxp; // 0x04: RX MAXP - __IO uint8_t rx_csrl; // 0x06: RX CSRL - __IO uint8_t rx_csrh; // 0x07: RX CSRH - __IO uint16_t rx_count; // 0x08: RX COUNT union { __IO uint8_t type0; // 0x0A: TYPE0 (host only) __IO uint8_t tx_type; // 0x0A: TX TYPE @@ -106,32 +123,71 @@ typedef struct TU_ATTR_PACKED { __IO uint8_t rx_interval; // 0x0D: RX INTERVAL __IO uint8_t reserved_0x0e; // 0x0E: Reserved union { - __IO uint8_t config_data; // 0x0F: CONFIG DATA + __IO uint8_t config_data0; // 0x0F: CONFIG DATA + struct { + __IO uint8_t utmi_data_width : 1; // [0] UTMI Data Width + __IO uint8_t softconn_en : 1; // [1] Soft Connect Enable + __IO uint8_t dynamic_fifo : 1; // [2] Dynamic FIFO Sizing + __IO uint8_t hb_tx_en : 1; // [3] High Bandwidth TX ISO Enable + __IO uint8_t hb_rx_en : 1; // [4] High Bandwidth RX ISO Enable + __IO uint8_t big_endian : 1; // [5] Big Endian + __IO uint8_t mp_tx_en : 1; // [6] Auto splitting BULK TX Enable + __IO uint8_t mp_rx_en : 1; // [7] Auto amalgamation BULK RX Enable + } config_data0_bit; + __IO uint8_t fifo_size; // 0x0F: FIFO_SIZE + struct { + __IO uint8_t tx : 4; // [3:0] TX FIFO Size + __IO uint8_t rx : 4; // [7:4] RX FIFO Size + }fifo_size_bit; }; } musb_ep_csr_t; TU_VERIFY_STATIC(sizeof(musb_ep_csr_t) == 16, "size is not correct"); -typedef struct { +typedef struct TU_ATTR_PACKED { //------------- Common -------------// __IO uint8_t faddr; // 0x00: FADDR - __IO uint8_t power; // 0x01: POWER + union { + __IO uint8_t power; // 0x01: POWER + struct { + __IO uint8_t suspend_mode_en : 1; // [0] SUSPEND Mode Enable + __IO uint8_t suspend_mode : 1; // [1] SUSPEND Mode + __IO uint8_t resume_mode : 1; // [2] RESUME + __IO uint8_t reset : 1; // [3] RESET + __IO uint8_t highspeed_mode : 1; // [4] High Speed Mode + __IO uint8_t highspeed_en : 1; // [5] High Speed Enable + __IO uint8_t soft_conn : 1; // [6] Soft Connect/Disconnect + __IO uint8_t iso_update : 1; // [7] Isochronous Update + } power_bit; + }; + + union { + struct { + __IO uint16_t intr_tx; // 0x02: INTR_TX + __IO uint16_t intr_rx; // 0x04: INTR_RX + }; + + __IO uint16_t intr_ep[2]; // 0x02-0x05: INTR_EP0-1 + }; - __IO uint16_t intr_tx; // 0x02: INTR_TX - __IO uint16_t intr_rx; // 0x04: INTR_RX + union { + struct { + __IO uint16_t intr_txen; // 0x06: INTR_TXEN + __IO uint16_t intr_rxen; // 0x08: INTR_RXEN + }; - __IO uint16_t intr_txen; // 0x06: INTR_TXEN - __IO uint16_t intr_rxen; // 0x08: INTR_RXEN + __IO uint16_t intren_ep[2]; // 0x06-0x09: INTREN_EP0-1 + }; - __IO uint8_t intrusb; // 0x0A: INTRUSB - __IO uint8_t intrusben; // 0x0B: INTRUSBEN + __IO uint8_t intr_usb; // 0x0A: INTRUSB + __IO uint8_t intr_usben; // 0x0B: INTRUSBEN __IO uint16_t frame; // 0x0C: FRAME __IO uint8_t index; // 0x0E: INDEX __IO uint8_t testmode; // 0x0F: TESTMODE - //------------- CSR (indexed) -------------// + //------------- Endpoint CSR (indexed) -------------// musb_ep_csr_t indexed_csr; // 0x10-0x1F: Indexed CSR 0-15 //------------- FIFOs -------------// @@ -142,35 +198,68 @@ typedef struct { __IO uint8_t misc; // 0x61: MISC //------------- Dynammic FIFO (indexed) -------------// - __IO uint8_t txfifo_sz; // 0x62: TXFIFO_SZ - __IO uint8_t rxfifo_sz; // 0x63: RXFIFO_SZ - __IO uint16_t txfifo_addr; // 0x64: TXFIFO_ADDR - __IO uint16_t rxfifo_addr; // 0x66: RXFIFO_ADDR + union { + struct { + __IO uint8_t txfifo_sz; // 0x62: TXFIFO_SZ + __IO uint8_t rxfifo_sz; // 0x63: RXFIFO_SZ + }; + __IO uint8_t fifo_size[2]; + }; + + union { + struct { + __IO uint16_t txfifo_addr; // 0x64: TXFIFO_ADDR + __IO uint16_t rxfifo_addr; // 0x66: RXFIFO_ADDR + }; + __IO uint16_t fifo_addr[2]; + }; - //------------- Additional Control/Status -------------// + //------------- Additional Control and Configuration -------------// + union { + __O uint32_t vcontrol; // 0x68: PHY VCONTROL + __IO uint32_t vstatus; // 0x68: PHY VSTATUS + }; union { - __O uint32_t vcontrol; // 0x68: VCONTROL - __IO uint32_t vstatus; // 0x68: VSTATUS + __IO uint16_t hwvers; // 0x6C: HWVERS + struct { + __IO uint16_t minor : 10; // [9:0] Minor + __IO uint16_t major : 5; // [14:10] Major + __IO uint16_t rc : 1; // [15] Release Candidate + } hwvers_bit; }; - __IO uint16_t hwvers; // 0x6c: HWVERS __R uint16_t rsv_0x6e_0x77[5]; // 0x6E-0x77: Reserved //------------- Additional Configuration -------------// - __IO uint8_t epinfo; // 0x78: EPINFO - __IO uint8_t raminfo; // 0x79: RAMINFO - __IO uint8_t softreset; // 0x7A: SOFTRESET (Analog), Link info + union { + __IO uint8_t epinfo; // 0x78: EPINFO + struct { + __IO uint8_t tx_ep_num : 4; // [3:0] TX Endpoints + __IO uint8_t rx_ep_num : 4; // [7:4] RX Endpoints + } epinfo_bit; + }; + union { + __IO uint8_t raminfo; // 0x79: RAMINFO + struct { + __IO uint8_t ram_bits : 4; // [3:0] RAM Address Bus Width + __IO uint8_t dma_channel : 4; // [7:4] DMA Channels + }raminfo_bit; + }; + union { + __IO uint8_t link_info; // 0x7A: LINK_INFO + __IO uint8_t adi_softreset; // 0x7A: AnalogDevice SOFTRESET + }; __IO uint8_t vplen; // 0x7B: VPLEN __IO uint8_t hs_eof1; // 0x7C: HS_EOF1 __IO uint8_t fs_eof1; // 0x7D: FS_EOF1 __IO uint8_t ls_eof1; // 0x7E: LS_EOF1 __IO uint8_t soft_rst; // 0x7F: SOFT_RST - //------------- Extended -------------// + //------------- Target Endpoints (multipoint option) -------------// __IO uint16_t ctuch; // 0x80: CTUCH __IO uint16_t cthsrtn; // 0x82: CTHSRTN __R uint32_t rsv_0x84_0xff[31]; // 0x84-0xFF: Reserved - //------------- Absolute CSR (used index to remap to Indexed above) -------------// + //------------- Non-Indexed Endpoint CSRs -------------// // TI tm4c can access this directly, but should use indexed_csr for portability musb_ep_csr_t ep_csr[16]; // 0x100-0x1FF: EP0-15 CSR } musb_regs_t; @@ -185,267 +274,151 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ return &musb_regs->indexed_csr; } -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FADDR register. -// -//***************************************************************************** -#define USB_FADDR_M 0x0000007F // Function Address -#define USB_FADDR_S 0 +//--------------------------------------------------------------------+ +// Register Bit Field +//--------------------------------------------------------------------+ -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_POWER register. -// -//***************************************************************************** -#define USB_POWER_ISOUP 0x00000080 // Isochronous Update -#define USB_POWER_SOFTCONN 0x00000040 // Soft Connect/Disconnect -#define USB_POWER_HSENAB 0x00000020 // High Speed Enable -#define USB_POWER_HSMODE 0x00000010 // High Speed Enable -#define USB_POWER_RESET 0x00000008 // RESET Signaling -#define USB_POWER_RESUME 0x00000004 // RESUME Signaling -#define USB_POWER_SUSPEND 0x00000002 // SUSPEND Mode -#define USB_POWER_PWRDNPHY 0x00000001 // Power Down PHY +// 0x01: Power +#define USB_POWER_ISOUP 0x0080 // Isochronous Update +#define USB_POWER_SOFTCONN 0x0040 // Soft Connect/Disconnect +#define USB_POWER_HSENAB 0x0020 // High Speed Enable +#define USB_POWER_HSMODE 0x0010 // High Speed Enable +#define USB_POWER_RESET 0x0008 // RESET Signaling +#define USB_POWER_RESUME 0x0004 // RESUME Signaling +#define USB_POWER_SUSPEND 0x0002 // SUSPEND Mode +#define USB_POWER_PWRDNPHY 0x0001 // Power Down PHY -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXIS register. -// -//***************************************************************************** -#define USB_TXIS_EP7 0x00000080 // TX Endpoint 7 Interrupt -#define USB_TXIS_EP6 0x00000040 // TX Endpoint 6 Interrupt -#define USB_TXIS_EP5 0x00000020 // TX Endpoint 5 Interrupt -#define USB_TXIS_EP4 0x00000010 // TX Endpoint 4 Interrupt -#define USB_TXIS_EP3 0x00000008 // TX Endpoint 3 Interrupt -#define USB_TXIS_EP2 0x00000004 // TX Endpoint 2 Interrupt -#define USB_TXIS_EP1 0x00000002 // TX Endpoint 1 Interrupt -#define USB_TXIS_EP0 0x00000001 // TX and RX Endpoint 0 Interrupt +// Interrupt TX/RX Status and Enable: each bit is for an endpoint -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXIS register. -// -//***************************************************************************** -#define USB_RXIS_EP7 0x00000080 // RX Endpoint 7 Interrupt -#define USB_RXIS_EP6 0x00000040 // RX Endpoint 6 Interrupt -#define USB_RXIS_EP5 0x00000020 // RX Endpoint 5 Interrupt -#define USB_RXIS_EP4 0x00000010 // RX Endpoint 4 Interrupt -#define USB_RXIS_EP3 0x00000008 // RX Endpoint 3 Interrupt -#define USB_RXIS_EP2 0x00000004 // RX Endpoint 2 Interrupt -#define USB_RXIS_EP1 0x00000002 // RX Endpoint 1 Interrupt +// 0x6c: HWVERS +#define MUSB_HWVERS_RC_SHIFT 15 +#define MUSB_HWVERS_RC_MASK 0x8000 +#define MUSB_HWVERS_MAJOR_SHIFT 10 +#define MUSB_HWVERS_MAJOR_MASK 0x7C00 +#define MUSB_HWVERS_MINOR_SHIFT 0 +#define MUSB_HWVERS_MINOR_MASK 0x03FF -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXIE register. -// -//***************************************************************************** -#define USB_TXIE_EP7 0x00000080 // TX Endpoint 7 Interrupt Enable -#define USB_TXIE_EP6 0x00000040 // TX Endpoint 6 Interrupt Enable -#define USB_TXIE_EP5 0x00000020 // TX Endpoint 5 Interrupt Enable -#define USB_TXIE_EP4 0x00000010 // TX Endpoint 4 Interrupt Enable -#define USB_TXIE_EP3 0x00000008 // TX Endpoint 3 Interrupt Enable -#define USB_TXIE_EP2 0x00000004 // TX Endpoint 2 Interrupt Enable -#define USB_TXIE_EP1 0x00000002 // TX Endpoint 1 Interrupt Enable -#define USB_TXIE_EP0 0x00000001 // TX and RX Endpoint 0 Interrupt - // Enable +// 0x12, 0x16: TX/RX CSRL +#define MUSB_CSRL_PACKET_READY(_rx) (1u << 0) +#define MUSB_CSRL_FLUSH_FIFO(_rx) (1u << ((_rx) ? 4 : 3)) +#define MUSB_CSRL_SEND_STALL(_rx) (1u << ((_rx) ? 5 : 4)) +#define MUSB_CSRL_SENT_STALL(_rx) (1u << ((_rx) ? 6 : 5)) +#define MUSB_CSRL_CLEAR_DATA_TOGGLE(_rx) (1u << ((_rx) ? 7 : 6)) + +// 0x13, 0x17: TX/RX CSRH +#define MUSB_CSRH_DISABLE_DOUBLE_PACKET(_rx) (1u << 1) -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXIE register. -// -//***************************************************************************** -#define USB_RXIE_EP7 0x00000080 // RX Endpoint 7 Interrupt Enable -#define USB_RXIE_EP6 0x00000040 // RX Endpoint 6 Interrupt Enable -#define USB_RXIE_EP5 0x00000020 // RX Endpoint 5 Interrupt Enable -#define USB_RXIE_EP4 0x00000010 // RX Endpoint 4 Interrupt Enable -#define USB_RXIE_EP3 0x00000008 // RX Endpoint 3 Interrupt Enable -#define USB_RXIE_EP2 0x00000004 // RX Endpoint 2 Interrupt Enable -#define USB_RXIE_EP1 0x00000002 // RX Endpoint 1 Interrupt Enable //***************************************************************************** // // The following are defines for the bit fields in the USB_O_IS register. // //***************************************************************************** -#define USB_IS_VBUSERR 0x00000080 // VBUS Error (OTG only) -#define USB_IS_SESREQ 0x00000040 // SESSION REQUEST (OTG only) -#define USB_IS_DISCON 0x00000020 // Session Disconnect (OTG only) -#define USB_IS_CONN 0x00000010 // Session Connect -#define USB_IS_SOF 0x00000008 // Start of Frame -#define USB_IS_BABBLE 0x00000004 // Babble Detected -#define USB_IS_RESET 0x00000004 // RESET Signaling Detected -#define USB_IS_RESUME 0x00000002 // RESUME Signaling Detected -#define USB_IS_SUSPEND 0x00000001 // SUSPEND Signaling Detected +#define USB_IS_VBUSERR 0x0080 // VBUS Error (OTG only) +#define USB_IS_SESREQ 0x0040 // SESSION REQUEST (OTG only) +#define USB_IS_DISCON 0x0020 // Session Disconnect (OTG only) +#define USB_IS_CONN 0x0010 // Session Connect +#define USB_IS_SOF 0x0008 // Start of Frame +#define USB_IS_BABBLE 0x0004 // Babble Detected +#define USB_IS_RESET 0x0004 // RESET Signaling Detected +#define USB_IS_RESUME 0x0002 // RESUME Signaling Detected +#define USB_IS_SUSPEND 0x0001 // SUSPEND Signaling Detected //***************************************************************************** // // The following are defines for the bit fields in the USB_O_IE register. // //***************************************************************************** -#define USB_IE_VBUSERR 0x00000080 // Enable VBUS Error Interrupt (OTG - // only) -#define USB_IE_SESREQ 0x00000040 // Enable Session Request (OTG - // only) -#define USB_IE_DISCON 0x00000020 // Enable Disconnect Interrupt -#define USB_IE_CONN 0x00000010 // Enable Connect Interrupt -#define USB_IE_SOF 0x00000008 // Enable Start-of-Frame Interrupt -#define USB_IE_BABBLE 0x00000004 // Enable Babble Interrupt -#define USB_IE_RESET 0x00000004 // Enable RESET Interrupt -#define USB_IE_RESUME 0x00000002 // Enable RESUME Interrupt -#define USB_IE_SUSPND 0x00000001 // Enable SUSPEND Interrupt +#define USB_IE_VBUSERR 0x0080 // Enable VBUS Error Interrupt (OTG only) +#define USB_IE_SESREQ 0x0040 // Enable Session Request (OTG only) +#define USB_IE_DISCON 0x0020 // Enable Disconnect Interrupt +#define USB_IE_CONN 0x0010 // Enable Connect Interrupt +#define USB_IE_SOF 0x0008 // Enable Start-of-Frame Interrupt +#define USB_IE_BABBLE 0x0004 // Enable Babble Interrupt +#define USB_IE_RESET 0x0004 // Enable RESET Interrupt +#define USB_IE_RESUME 0x0002 // Enable RESUME Interrupt +#define USB_IE_SUSPND 0x0001 // Enable SUSPEND Interrupt //***************************************************************************** // // The following are defines for the bit fields in the USB_O_FRAME register. // //***************************************************************************** -#define USB_FRAME_M 0x000007FF // Frame Number +#define USB_FRAME_M 0x07FF // Frame Number #define USB_FRAME_S 0 -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_EPIDX register. -// -//***************************************************************************** -#define USB_EPIDX_EPIDX_M 0x0000000F // Endpoint Index -#define USB_EPIDX_EPIDX_S 0 - //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TEST register. // //***************************************************************************** -#define USB_TEST_FORCEH 0x00000080 // Force Host Mode -#define USB_TEST_FIFOACC 0x00000040 // FIFO Access -#define USB_TEST_FORCEFS 0x00000020 // Force Full-Speed Mode -#define USB_TEST_FORCEHS 0x00000010 // Force High-Speed Mode -#define USB_TEST_TESTPKT 0x00000008 // Test Packet Mode Enable -#define USB_TEST_TESTK 0x00000004 // Test_K Mode Enable -#define USB_TEST_TESTJ 0x00000002 // Test_J Mode Enable -#define USB_TEST_TESTSE0NAK 0x00000001 // Test_SE0_NAK Test Mode Enable - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO0 register. -// -//***************************************************************************** -#define USB_FIFO0_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO0_EPDATA_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO1 register. -// -//***************************************************************************** -#define USB_FIFO1_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO1_EPDATA_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO2 register. -// -//***************************************************************************** -#define USB_FIFO2_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO2_EPDATA_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO3 register. -// -//***************************************************************************** -#define USB_FIFO3_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO3_EPDATA_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO4 register. -// -//***************************************************************************** -#define USB_FIFO4_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO4_EPDATA_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO5 register. -// -//***************************************************************************** -#define USB_FIFO5_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO5_EPDATA_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO6 register. -// -//***************************************************************************** -#define USB_FIFO6_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO6_EPDATA_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO7 register. -// -//***************************************************************************** -#define USB_FIFO7_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO7_EPDATA_S 0 +#define USB_TEST_FORCEH 0x0080 // Force Host Mode +#define USB_TEST_FIFOACC 0x0040 // FIFO Access +#define USB_TEST_FORCEFS 0x0020 // Force Full-Speed Mode +#define USB_TEST_FORCEHS 0x0010 // Force High-Speed Mode +#define USB_TEST_TESTPKT 0x0008 // Test Packet Mode Enable +#define USB_TEST_TESTK 0x0004 // Test_K Mode Enable +#define USB_TEST_TESTJ 0x0002 // Test_J Mode Enable +#define USB_TEST_TESTSE0NAK 0x0001 // Test_SE0_NAK Test Mode Enable //***************************************************************************** // // The following are defines for the bit fields in the USB_O_DEVCTL register. // //***************************************************************************** -#define USB_DEVCTL_DEV 0x00000080 // Device Mode (OTG only) -#define USB_DEVCTL_FSDEV 0x00000040 // Full-Speed Device Detected -#define USB_DEVCTL_LSDEV 0x00000020 // Low-Speed Device Detected -#define USB_DEVCTL_VBUS_M 0x00000018 // VBUS Level (OTG only) -#define USB_DEVCTL_VBUS_NONE 0x00000000 // Below SessionEnd -#define USB_DEVCTL_VBUS_SEND 0x00000008 // Above SessionEnd, below AValid -#define USB_DEVCTL_VBUS_AVALID 0x00000010 // Above AValid, below VBUSValid -#define USB_DEVCTL_VBUS_VALID 0x00000018 // Above VBUSValid -#define USB_DEVCTL_HOST 0x00000004 // Host Mode -#define USB_DEVCTL_HOSTREQ 0x00000002 // Host Request (OTG only) -#define USB_DEVCTL_SESSION 0x00000001 // Session Start/End (OTG only) +#define USB_DEVCTL_DEV 0x0080 // Device Mode (OTG only) +#define USB_DEVCTL_FSDEV 0x0040 // Full-Speed Device Detected +#define USB_DEVCTL_LSDEV 0x0020 // Low-Speed Device Detected +#define USB_DEVCTL_VBUS_M 0x0018 // VBUS Level (OTG only) +#define USB_DEVCTL_VBUS_NONE 0x0000 // Below SessionEnd +#define USB_DEVCTL_VBUS_SEND 0x0008 // Above SessionEnd, below AValid +#define USB_DEVCTL_VBUS_AVALID 0x0010 // Above AValid, below VBUSValid +#define USB_DEVCTL_VBUS_VALID 0x0018 // Above VBUSValid +#define USB_DEVCTL_HOST 0x0004 // Host Mode +#define USB_DEVCTL_HOSTREQ 0x0002 // Host Request (OTG only) +#define USB_DEVCTL_SESSION 0x0001 // Session Start/End (OTG only) //***************************************************************************** // // The following are defines for the bit fields in the USB_O_CCONF register. // //***************************************************************************** -#define USB_CCONF_TXEDMA 0x00000002 // TX Early DMA Enable -#define USB_CCONF_RXEDMA 0x00000001 // TX Early DMA Enable +#define USB_CCONF_TXEDMA 0x0002 // TX Early DMA Enable +#define USB_CCONF_RXEDMA 0x0001 // TX Early DMA Enable //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXFIFOSZ register. // //***************************************************************************** -#define USB_TXFIFOSZ_DPB 0x00000010 // Double Packet Buffer Support -#define USB_TXFIFOSZ_SIZE_M 0x0000000F // Max Packet Size -#define USB_TXFIFOSZ_SIZE_8 0x00000000 // 8 -#define USB_TXFIFOSZ_SIZE_16 0x00000001 // 16 -#define USB_TXFIFOSZ_SIZE_32 0x00000002 // 32 -#define USB_TXFIFOSZ_SIZE_64 0x00000003 // 64 -#define USB_TXFIFOSZ_SIZE_128 0x00000004 // 128 -#define USB_TXFIFOSZ_SIZE_256 0x00000005 // 256 -#define USB_TXFIFOSZ_SIZE_512 0x00000006 // 512 -#define USB_TXFIFOSZ_SIZE_1024 0x00000007 // 1024 -#define USB_TXFIFOSZ_SIZE_2048 0x00000008 // 2048 +#define USB_TXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support +#define USB_TXFIFOSZ_SIZE_M 0x000F // Max Packet Size +#define USB_TXFIFOSZ_SIZE_8 0x0000 // 8 +#define USB_TXFIFOSZ_SIZE_16 0x0001 // 16 +#define USB_TXFIFOSZ_SIZE_32 0x0002 // 32 +#define USB_TXFIFOSZ_SIZE_64 0x0003 // 64 +#define USB_TXFIFOSZ_SIZE_128 0x0004 // 128 +#define USB_TXFIFOSZ_SIZE_256 0x0005 // 256 +#define USB_TXFIFOSZ_SIZE_512 0x0006 // 512 +#define USB_TXFIFOSZ_SIZE_1024 0x0007 // 1024 +#define USB_TXFIFOSZ_SIZE_2048 0x0008 // 2048 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXFIFOSZ register. // //***************************************************************************** -#define USB_RXFIFOSZ_DPB 0x00000010 // Double Packet Buffer Support -#define USB_RXFIFOSZ_SIZE_M 0x0000000F // Max Packet Size -#define USB_RXFIFOSZ_SIZE_8 0x00000000 // 8 -#define USB_RXFIFOSZ_SIZE_16 0x00000001 // 16 -#define USB_RXFIFOSZ_SIZE_32 0x00000002 // 32 -#define USB_RXFIFOSZ_SIZE_64 0x00000003 // 64 -#define USB_RXFIFOSZ_SIZE_128 0x00000004 // 128 -#define USB_RXFIFOSZ_SIZE_256 0x00000005 // 256 -#define USB_RXFIFOSZ_SIZE_512 0x00000006 // 512 -#define USB_RXFIFOSZ_SIZE_1024 0x00000007 // 1024 -#define USB_RXFIFOSZ_SIZE_2048 0x00000008 // 2048 +#define USB_RXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support +#define USB_RXFIFOSZ_SIZE_M 0x000F // Max Packet Size +#define USB_RXFIFOSZ_SIZE_8 0x0000 // 8 +#define USB_RXFIFOSZ_SIZE_16 0x0001 // 16 +#define USB_RXFIFOSZ_SIZE_32 0x0002 // 32 +#define USB_RXFIFOSZ_SIZE_64 0x0003 // 64 +#define USB_RXFIFOSZ_SIZE_128 0x0004 // 128 +#define USB_RXFIFOSZ_SIZE_256 0x0005 // 256 +#define USB_RXFIFOSZ_SIZE_512 0x0006 // 512 +#define USB_RXFIFOSZ_SIZE_1024 0x0007 // 1024 +#define USB_RXFIFOSZ_SIZE_2048 0x0008 // 2048 //***************************************************************************** // @@ -453,7 +426,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXFIFOADD_ADDR_M 0x000001FF // Transmit/Receive Start Address +#define USB_TXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address #define USB_TXFIFOADD_ADDR_S 0 //***************************************************************************** @@ -462,7 +435,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXFIFOADD_ADDR_M 0x000001FF // Transmit/Receive Start Address +#define USB_RXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address #define USB_RXFIFOADD_ADDR_S 0 //***************************************************************************** @@ -471,10 +444,8 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_ULPIVBUSCTL_USEEXTVBUSIND \ - 0x00000002 // Use External VBUS Indicator -#define USB_ULPIVBUSCTL_USEEXTVBUS \ - 0x00000001 // Use External VBUS +#define USB_ULPIVBUSCTL_USEEXTVBUSIND 0x0002 // Use External VBUS Indicator +#define USB_ULPIVBUSCTL_USEEXTVBUS 0x0001 // Use External VBUS //***************************************************************************** // @@ -482,18 +453,15 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_ULPIREGDATA_REGDATA_M \ - 0x000000FF // Register Data -#define USB_ULPIREGDATA_REGDATA_S \ - 0 - +#define USB_ULPIREGDATA_REGDATA_M 0x00FF // Register Data +#define USB_ULPIREGDATA_REGDATA_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_ULPIREGADDR // register. // //***************************************************************************** -#define USB_ULPIREGADDR_ADDR_M 0x000000FF // Register Address +#define USB_ULPIREGADDR_ADDR_M 0x00FF // Register Address #define USB_ULPIREGADDR_ADDR_S 0 //***************************************************************************** @@ -502,17 +470,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_ULPIREGCTL_RDWR 0x00000004 // Read/Write Control -#define USB_ULPIREGCTL_REGCMPLT 0x00000002 // Register Access Complete -#define USB_ULPIREGCTL_REGACC 0x00000001 // Initiate Register Access +#define USB_ULPIREGCTL_RDWR 0x0004 // Read/Write Control +#define USB_ULPIREGCTL_REGCMPLT 0x0002 // Register Access Complete +#define USB_ULPIREGCTL_REGACC 0x0001 // Initiate Register Access //***************************************************************************** // // The following are defines for the bit fields in the USB_O_EPINFO register. // //***************************************************************************** -#define USB_EPINFO_RXEP_M 0x000000F0 // RX Endpoints -#define USB_EPINFO_TXEP_M 0x0000000F // TX Endpoints +#define USB_EPINFO_RXEP_M 0x00F0 // RX Endpoints +#define USB_EPINFO_TXEP_M 0x000F // TX Endpoints #define USB_EPINFO_RXEP_S 4 #define USB_EPINFO_TXEP_S 0 @@ -521,8 +489,8 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RAMINFO register. // //***************************************************************************** -#define USB_RAMINFO_DMACHAN_M 0x000000F0 // DMA Channels -#define USB_RAMINFO_RAMBITS_M 0x0000000F // RAM Address Bus Width +#define USB_RAMINFO_DMACHAN_M 0x00F0 // DMA Channels +#define USB_RAMINFO_RAMBITS_M 0x000F // RAM Address Bus Width #define USB_RAMINFO_DMACHAN_S 4 #define USB_RAMINFO_RAMBITS_S 0 @@ -531,8 +499,8 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_CONTIM register. // //***************************************************************************** -#define USB_CONTIM_WTCON_M 0x000000F0 // Connect Wait -#define USB_CONTIM_WTID_M 0x0000000F // Wait ID +#define USB_CONTIM_WTCON_M 0x00F0 // Connect Wait +#define USB_CONTIM_WTID_M 0x000F // Wait ID #define USB_CONTIM_WTCON_S 4 #define USB_CONTIM_WTID_S 0 @@ -541,7 +509,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_VPLEN register. // //***************************************************************************** -#define USB_VPLEN_VPLEN_M 0x000000FF // VBUS Pulse Length +#define USB_VPLEN_VPLEN_M 0x00FF // VBUS Pulse Length #define USB_VPLEN_VPLEN_S 0 //***************************************************************************** @@ -549,7 +517,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_HSEOF register. // //***************************************************************************** -#define USB_HSEOF_HSEOFG_M 0x000000FF // HIgh-Speed End-of-Frame Gap +#define USB_HSEOF_HSEOFG_M 0x00FF // HIgh-Speed End-of-Frame Gap #define USB_HSEOF_HSEOFG_S 0 //***************************************************************************** @@ -557,7 +525,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_FSEOF register. // //***************************************************************************** -#define USB_FSEOF_FSEOFG_M 0x000000FF // Full-Speed End-of-Frame Gap +#define USB_FSEOF_FSEOFG_M 0x00FF // Full-Speed End-of-Frame Gap #define USB_FSEOF_FSEOFG_S 0 //***************************************************************************** @@ -565,449 +533,44 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_LSEOF register. // //***************************************************************************** -#define USB_LSEOF_LSEOFG_M 0x000000FF // Low-Speed End-of-Frame Gap +#define USB_LSEOF_LSEOFG_M 0x00FF // Low-Speed End-of-Frame Gap #define USB_LSEOF_LSEOFG_S 0 -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR0 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR0_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR0_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR0 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR0_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR0_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT0 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT0_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT0_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR1 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR1_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR1_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR1 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR1_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR1_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT1 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT1_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT1_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXFUNCADDR1 -// register. -// -//***************************************************************************** -#define USB_RXFUNCADDR1_ADDR_M 0x0000007F // Device Address -#define USB_RXFUNCADDR1_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBADDR1 -// register. -// -//***************************************************************************** -#define USB_RXHUBADDR1_ADDR_M 0x0000007F // Hub Address -#define USB_RXHUBADDR1_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBPORT1 -// register. -// -//***************************************************************************** -#define USB_RXHUBPORT1_PORT_M 0x0000007F // Hub Port -#define USB_RXHUBPORT1_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR2 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR2_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR2_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR2 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR2_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR2_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT2 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT2_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT2_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXFUNCADDR2 -// register. -// -//***************************************************************************** -#define USB_RXFUNCADDR2_ADDR_M 0x0000007F // Device Address -#define USB_RXFUNCADDR2_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBADDR2 -// register. -// -//***************************************************************************** -#define USB_RXHUBADDR2_ADDR_M 0x0000007F // Hub Address -#define USB_RXHUBADDR2_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBPORT2 -// register. -// -//***************************************************************************** -#define USB_RXHUBPORT2_PORT_M 0x0000007F // Hub Port -#define USB_RXHUBPORT2_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR3 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR3_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR3_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR3 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR3_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR3_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT3 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT3_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT3_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXFUNCADDR3 -// register. -// -//***************************************************************************** -#define USB_RXFUNCADDR3_ADDR_M 0x0000007F // Device Address -#define USB_RXFUNCADDR3_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBADDR3 -// register. -// -//***************************************************************************** -#define USB_RXHUBADDR3_ADDR_M 0x0000007F // Hub Address -#define USB_RXHUBADDR3_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBPORT3 -// register. -// -//***************************************************************************** -#define USB_RXHUBPORT3_PORT_M 0x0000007F // Hub Port -#define USB_RXHUBPORT3_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR4 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR4_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR4_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR4 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR4_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR4_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT4 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT4_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT4_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXFUNCADDR4 -// register. -// -//***************************************************************************** -#define USB_RXFUNCADDR4_ADDR_M 0x0000007F // Device Address -#define USB_RXFUNCADDR4_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBADDR4 -// register. -// -//***************************************************************************** -#define USB_RXHUBADDR4_ADDR_M 0x0000007F // Hub Address -#define USB_RXHUBADDR4_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBPORT4 -// register. -// -//***************************************************************************** -#define USB_RXHUBPORT4_PORT_M 0x0000007F // Hub Port -#define USB_RXHUBPORT4_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR5 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR5_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR5_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR5 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR5_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR5_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT5 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT5_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT5_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXFUNCADDR5 -// register. -// -//***************************************************************************** -#define USB_RXFUNCADDR5_ADDR_M 0x0000007F // Device Address -#define USB_RXFUNCADDR5_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBADDR5 -// register. -// -//***************************************************************************** -#define USB_RXHUBADDR5_ADDR_M 0x0000007F // Hub Address -#define USB_RXHUBADDR5_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBPORT5 -// register. -// -//***************************************************************************** -#define USB_RXHUBPORT5_PORT_M 0x0000007F // Hub Port -#define USB_RXHUBPORT5_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR6 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR6_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR6_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR6 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR6_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR6_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT6 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT6_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT6_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXFUNCADDR6 -// register. -// -//***************************************************************************** -#define USB_RXFUNCADDR6_ADDR_M 0x0000007F // Device Address -#define USB_RXFUNCADDR6_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBADDR6 -// register. -// -//***************************************************************************** -#define USB_RXHUBADDR6_ADDR_M 0x0000007F // Hub Address -#define USB_RXHUBADDR6_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBPORT6 -// register. -// -//***************************************************************************** -#define USB_RXHUBPORT6_PORT_M 0x0000007F // Hub Port -#define USB_RXHUBPORT6_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR7 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR7_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR7_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR7 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR7_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR7_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT7 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT7_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT7_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXFUNCADDR7 -// register. -// -//***************************************************************************** -#define USB_RXFUNCADDR7_ADDR_M 0x0000007F // Device Address -#define USB_RXFUNCADDR7_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBADDR7 -// register. -// -//***************************************************************************** -#define USB_RXHUBADDR7_ADDR_M 0x0000007F // Hub Address -#define USB_RXHUBADDR7_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBPORT7 -// register. -// -//***************************************************************************** -#define USB_RXHUBPORT7_PORT_M 0x0000007F // Hub Port -#define USB_RXHUBPORT7_PORT_S 0 - //***************************************************************************** // // The following are defines for the bit fields in the USB_O_CSRL0 register. // //***************************************************************************** -#define USB_CSRL0_NAKTO 0x00000080 // NAK Timeout -#define USB_CSRL0_SETENDC 0x00000080 // Setup End Clear -#define USB_CSRL0_STATUS 0x00000040 // STATUS Packet -#define USB_CSRL0_RXRDYC 0x00000040 // RXRDY Clear -#define USB_CSRL0_REQPKT 0x00000020 // Request Packet -#define USB_CSRL0_STALL 0x00000020 // Send Stall -#define USB_CSRL0_SETEND 0x00000010 // Setup End -#define USB_CSRL0_ERROR 0x00000010 // Error -#define USB_CSRL0_DATAEND 0x00000008 // Data End -#define USB_CSRL0_SETUP 0x00000008 // Setup Packet -#define USB_CSRL0_STALLED 0x00000004 // Endpoint Stalled -#define USB_CSRL0_TXRDY 0x00000002 // Transmit Packet Ready -#define USB_CSRL0_RXRDY 0x00000001 // Receive Packet Ready +#define USB_CSRL0_NAKTO 0x0080 // NAK Timeout +#define USB_CSRL0_SETENDC 0x0080 // Setup End Clear +#define USB_CSRL0_STATUS 0x0040 // STATUS Packet +#define USB_CSRL0_RXRDYC 0x0040 // RXRDY Clear +#define USB_CSRL0_REQPKT 0x0020 // Request Packet +#define USB_CSRL0_STALL 0x0020 // Send Stall +#define USB_CSRL0_SETEND 0x0010 // Setup End +#define USB_CSRL0_ERROR 0x0010 // Error +#define USB_CSRL0_DATAEND 0x0008 // Data End +#define USB_CSRL0_SETUP 0x0008 // Setup Packet +#define USB_CSRL0_STALLED 0x0004 // Endpoint Stalled +#define USB_CSRL0_TXRDY 0x0002 // Transmit Packet Ready +#define USB_CSRL0_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_CSRH0 register. // //***************************************************************************** -#define USB_CSRH0_DISPING 0x00000008 // PING Disable -#define USB_CSRH0_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_CSRH0_DT 0x00000002 // Data Toggle -#define USB_CSRH0_FLUSH 0x00000001 // Flush FIFO +#define USB_CSRH0_DISPING 0x0008 // PING Disable +#define USB_CSRH0_DTWE 0x0004 // Data Toggle Write Enable +#define USB_CSRH0_DT 0x0002 // Data Toggle +#define USB_CSRH0_FLUSH 0x0001 // Flush FIFO //***************************************************************************** // // The following are defines for the bit fields in the USB_O_COUNT0 register. // //***************************************************************************** -#define USB_COUNT0_COUNT_M 0x0000007F // FIFO Count +#define USB_COUNT0_COUNT_M 0x007F // FIFO Count #define USB_COUNT0_COUNT_S 0 //***************************************************************************** @@ -1015,17 +578,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TYPE0 register. // //***************************************************************************** -#define USB_TYPE0_SPEED_M 0x000000C0 // Operating Speed -#define USB_TYPE0_SPEED_HIGH 0x00000040 // High -#define USB_TYPE0_SPEED_FULL 0x00000080 // Full -#define USB_TYPE0_SPEED_LOW 0x000000C0 // Low +#define USB_TYPE0_SPEED_M 0x00C0 // Operating Speed +#define USB_TYPE0_SPEED_HIGH 0x0040 // High +#define USB_TYPE0_SPEED_FULL 0x0080 // Full +#define USB_TYPE0_SPEED_LOW 0x00C0 // Low //***************************************************************************** // // The following are defines for the bit fields in the USB_O_NAKLMT register. // //***************************************************************************** -#define USB_NAKLMT_NAKLMT_M 0x0000001F // EP0 NAK Limit +#define USB_NAKLMT_NAKLMT_M 0x001F // EP0 NAK Limit #define USB_NAKLMT_NAKLMT_S 0 //***************************************************************************** @@ -1033,7 +596,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXMAXP1 register. // //***************************************************************************** -#define USB_TXMAXP1_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP1_MAXLOAD_M 0x07FF // Maximum Payload #define USB_TXMAXP1_MAXLOAD_S 0 //***************************************************************************** @@ -1041,37 +604,37 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXCSRL1 register. // //***************************************************************************** -#define USB_TXCSRL1_NAKTO 0x00000080 // NAK Timeout -#define USB_TXCSRL1_CLRDT 0x00000040 // Clear Data Toggle -#define USB_TXCSRL1_STALLED 0x00000020 // Endpoint Stalled -#define USB_TXCSRL1_STALL 0x00000010 // Send STALL -#define USB_TXCSRL1_SETUP 0x00000010 // Setup Packet -#define USB_TXCSRL1_FLUSH 0x00000008 // Flush FIFO -#define USB_TXCSRL1_ERROR 0x00000004 // Error -#define USB_TXCSRL1_UNDRN 0x00000004 // Underrun -#define USB_TXCSRL1_FIFONE 0x00000002 // FIFO Not Empty -#define USB_TXCSRL1_TXRDY 0x00000001 // Transmit Packet Ready +#define USB_TXCSRL1_NAKTO 0x0080 // NAK Timeout +#define USB_TXCSRL1_CLRDT 0x0040 // Clear Data Toggle +#define USB_TXCSRL1_STALLED 0x0020 // Endpoint Stalled +#define USB_TXCSRL1_STALL 0x0010 // Send STALL +#define USB_TXCSRL1_SETUP 0x0010 // Setup Packet +#define USB_TXCSRL1_FLUSH 0x0008 // Flush FIFO +#define USB_TXCSRL1_ERROR 0x0004 // Error +#define USB_TXCSRL1_UNDRN 0x0004 // Underrun +#define USB_TXCSRL1_FIFONE 0x0002 // FIFO Not Empty +#define USB_TXCSRL1_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRH1 register. // //***************************************************************************** -#define USB_TXCSRH1_AUTOSET 0x00000080 // Auto Set -#define USB_TXCSRH1_ISO 0x00000040 // Isochronous Transfers -#define USB_TXCSRH1_MODE 0x00000020 // Mode -#define USB_TXCSRH1_DMAEN 0x00000010 // DMA Request Enable -#define USB_TXCSRH1_FDT 0x00000008 // Force Data Toggle -#define USB_TXCSRH1_DMAMOD 0x00000004 // DMA Request Mode -#define USB_TXCSRH1_DTWE 0x00000002 // Data Toggle Write Enable -#define USB_TXCSRH1_DT 0x00000001 // Data Toggle +#define USB_TXCSRH1_AUTOSET 0x0080 // Auto Set +#define USB_TXCSRH1_ISO 0x0040 // Isochronous Transfers +#define USB_TXCSRH1_MODE 0x0020 // Mode +#define USB_TXCSRH1_DMAEN 0x0010 // DMA Request Enable +#define USB_TXCSRH1_FDT 0x0008 // Force Data Toggle +#define USB_TXCSRH1_DMAMOD 0x0004 // DMA Request Mode +#define USB_TXCSRH1_DTWE 0x0002 // Data Toggle Write Enable +#define USB_TXCSRH1_DT 0x0001 // Data Toggle //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXMAXP1 register. // //***************************************************************************** -#define USB_RXMAXP1_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP1_MAXLOAD_M 0x07FF // Maximum Payload #define USB_RXMAXP1_MAXLOAD_S 0 //***************************************************************************** @@ -1079,33 +642,33 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCSRL1 register. // //***************************************************************************** -#define USB_RXCSRL1_CLRDT 0x00000080 // Clear Data Toggle -#define USB_RXCSRL1_STALLED 0x00000040 // Endpoint Stalled -#define USB_RXCSRL1_STALL 0x00000020 // Send STALL -#define USB_RXCSRL1_REQPKT 0x00000020 // Request Packet -#define USB_RXCSRL1_FLUSH 0x00000010 // Flush FIFO -#define USB_RXCSRL1_DATAERR 0x00000008 // Data Error -#define USB_RXCSRL1_NAKTO 0x00000008 // NAK Timeout -#define USB_RXCSRL1_OVER 0x00000004 // Overrun -#define USB_RXCSRL1_ERROR 0x00000004 // Error -#define USB_RXCSRL1_FULL 0x00000002 // FIFO Full -#define USB_RXCSRL1_RXRDY 0x00000001 // Receive Packet Ready +#define USB_RXCSRL1_CLRDT 0x0080 // Clear Data Toggle +#define USB_RXCSRL1_STALLED 0x0040 // Endpoint Stalled +#define USB_RXCSRL1_STALL 0x0020 // Send STALL +#define USB_RXCSRL1_REQPKT 0x0020 // Request Packet +#define USB_RXCSRL1_FLUSH 0x0010 // Flush FIFO +#define USB_RXCSRL1_DATAERR 0x0008 // Data Error +#define USB_RXCSRL1_NAKTO 0x0008 // NAK Timeout +#define USB_RXCSRL1_OVER 0x0004 // Overrun +#define USB_RXCSRL1_ERROR 0x0004 // Error +#define USB_RXCSRL1_FULL 0x0002 // FIFO Full +#define USB_RXCSRL1_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRH1 register. // //***************************************************************************** -#define USB_RXCSRH1_AUTOCL 0x00000080 // Auto Clear -#define USB_RXCSRH1_AUTORQ 0x00000040 // Auto Request -#define USB_RXCSRH1_ISO 0x00000040 // Isochronous Transfers -#define USB_RXCSRH1_DMAEN 0x00000020 // DMA Request Enable -#define USB_RXCSRH1_DISNYET 0x00000010 // Disable NYET -#define USB_RXCSRH1_PIDERR 0x00000010 // PID Error -#define USB_RXCSRH1_DMAMOD 0x00000008 // DMA Request Mode -#define USB_RXCSRH1_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_RXCSRH1_DT 0x00000002 // Data Toggle -#define USB_RXCSRH1_INCOMPRX 0x00000001 // Incomplete RX Transmission +#define USB_RXCSRH1_AUTOCL 0x0080 // Auto Clear +#define USB_RXCSRH1_AUTORQ 0x0040 // Auto Request +#define USB_RXCSRH1_ISO 0x0040 // Isochronous Transfers +#define USB_RXCSRH1_DMAEN 0x0020 // DMA Request Enable +#define USB_RXCSRH1_DISNYET 0x0010 // Disable NYET +#define USB_RXCSRH1_PIDERR 0x0010 // PID Error +#define USB_RXCSRH1_DMAMOD 0x0008 // DMA Request Mode +#define USB_RXCSRH1_DTWE 0x0004 // Data Toggle Write Enable +#define USB_RXCSRH1_DT 0x0002 // Data Toggle +#define USB_RXCSRH1_INCOMPRX 0x0001 // Incomplete RX Transmission // Status //***************************************************************************** @@ -1113,7 +676,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCOUNT1 register. // //***************************************************************************** -#define USB_RXCOUNT1_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT1_COUNT_M 0x1FFF // Receive Packet Count #define USB_RXCOUNT1_COUNT_S 0 //***************************************************************************** @@ -1121,17 +684,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXTYPE1 register. // //***************************************************************************** -#define USB_TXTYPE1_SPEED_M 0x000000C0 // Operating Speed -#define USB_TXTYPE1_SPEED_DFLT 0x00000000 // Default -#define USB_TXTYPE1_SPEED_HIGH 0x00000040 // High -#define USB_TXTYPE1_SPEED_FULL 0x00000080 // Full -#define USB_TXTYPE1_SPEED_LOW 0x000000C0 // Low -#define USB_TXTYPE1_PROTO_M 0x00000030 // Protocol -#define USB_TXTYPE1_PROTO_CTRL 0x00000000 // Control -#define USB_TXTYPE1_PROTO_ISOC 0x00000010 // Isochronous -#define USB_TXTYPE1_PROTO_BULK 0x00000020 // Bulk -#define USB_TXTYPE1_PROTO_INT 0x00000030 // Interrupt -#define USB_TXTYPE1_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE1_SPEED_M 0x00C0 // Operating Speed +#define USB_TXTYPE1_SPEED_DFLT 0x0000 // Default +#define USB_TXTYPE1_SPEED_HIGH 0x0040 // High +#define USB_TXTYPE1_SPEED_FULL 0x0080 // Full +#define USB_TXTYPE1_SPEED_LOW 0x00C0 // Low +#define USB_TXTYPE1_PROTO_M 0x0030 // Protocol +#define USB_TXTYPE1_PROTO_CTRL 0x0000 // Control +#define USB_TXTYPE1_PROTO_ISOC 0x0010 // Isochronous +#define USB_TXTYPE1_PROTO_BULK 0x0020 // Bulk +#define USB_TXTYPE1_PROTO_INT 0x0030 // Interrupt +#define USB_TXTYPE1_TEP_M 0x000F // Target Endpoint Number #define USB_TXTYPE1_TEP_S 0 //***************************************************************************** @@ -1140,31 +703,27 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXINTERVAL1_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_TXINTERVAL1_TXPOLL_M \ - 0x000000FF // TX Polling -#define USB_TXINTERVAL1_TXPOLL_S \ - 0 -#define USB_TXINTERVAL1_NAKLMT_S \ - 0 +#define USB_TXINTERVAL1_NAKLMT_M 0x00FF // NAK Limit +#define USB_TXINTERVAL1_TXPOLL_M 0x00FF // TX Polling +#define USB_TXINTERVAL1_TXPOLL_S 0 +#define USB_TXINTERVAL1_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXTYPE1 register. // //***************************************************************************** -#define USB_RXTYPE1_SPEED_M 0x000000C0 // Operating Speed -#define USB_RXTYPE1_SPEED_DFLT 0x00000000 // Default -#define USB_RXTYPE1_SPEED_HIGH 0x00000040 // High -#define USB_RXTYPE1_SPEED_FULL 0x00000080 // Full -#define USB_RXTYPE1_SPEED_LOW 0x000000C0 // Low -#define USB_RXTYPE1_PROTO_M 0x00000030 // Protocol -#define USB_RXTYPE1_PROTO_CTRL 0x00000000 // Control -#define USB_RXTYPE1_PROTO_ISOC 0x00000010 // Isochronous -#define USB_RXTYPE1_PROTO_BULK 0x00000020 // Bulk -#define USB_RXTYPE1_PROTO_INT 0x00000030 // Interrupt -#define USB_RXTYPE1_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE1_SPEED_M 0x00C0 // Operating Speed +#define USB_RXTYPE1_SPEED_DFLT 0x0000 // Default +#define USB_RXTYPE1_SPEED_HIGH 0x0040 // High +#define USB_RXTYPE1_SPEED_FULL 0x0080 // Full +#define USB_RXTYPE1_SPEED_LOW 0x00C0 // Low +#define USB_RXTYPE1_PROTO_M 0x0030 // Protocol +#define USB_RXTYPE1_PROTO_CTRL 0x0000 // Control +#define USB_RXTYPE1_PROTO_ISOC 0x0010 // Isochronous +#define USB_RXTYPE1_PROTO_BULK 0x0020 // Bulk +#define USB_RXTYPE1_PROTO_INT 0x0030 // Interrupt +#define USB_RXTYPE1_TEP_M 0x000F // Target Endpoint Number #define USB_RXTYPE1_TEP_S 0 //***************************************************************************** @@ -1173,21 +732,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXINTERVAL1_TXPOLL_M \ - 0x000000FF // RX Polling -#define USB_RXINTERVAL1_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_RXINTERVAL1_TXPOLL_S \ - 0 -#define USB_RXINTERVAL1_NAKLMT_S \ - 0 +#define USB_RXINTERVAL1_TXPOLL_M 0x00FF // RX Polling +#define USB_RXINTERVAL1_NAKLMT_M 0x00FF // NAK Limit +#define USB_RXINTERVAL1_TXPOLL_S 0 +#define USB_RXINTERVAL1_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXMAXP2 register. // //***************************************************************************** -#define USB_TXMAXP2_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP2_MAXLOAD_M 0x07FF // Maximum Payload #define USB_TXMAXP2_MAXLOAD_S 0 //***************************************************************************** @@ -1195,37 +750,37 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXCSRL2 register. // //***************************************************************************** -#define USB_TXCSRL2_NAKTO 0x00000080 // NAK Timeout -#define USB_TXCSRL2_CLRDT 0x00000040 // Clear Data Toggle -#define USB_TXCSRL2_STALLED 0x00000020 // Endpoint Stalled -#define USB_TXCSRL2_SETUP 0x00000010 // Setup Packet -#define USB_TXCSRL2_STALL 0x00000010 // Send STALL -#define USB_TXCSRL2_FLUSH 0x00000008 // Flush FIFO -#define USB_TXCSRL2_ERROR 0x00000004 // Error -#define USB_TXCSRL2_UNDRN 0x00000004 // Underrun -#define USB_TXCSRL2_FIFONE 0x00000002 // FIFO Not Empty -#define USB_TXCSRL2_TXRDY 0x00000001 // Transmit Packet Ready +#define USB_TXCSRL2_NAKTO 0x0080 // NAK Timeout +#define USB_TXCSRL2_CLRDT 0x0040 // Clear Data Toggle +#define USB_TXCSRL2_STALLED 0x0020 // Endpoint Stalled +#define USB_TXCSRL2_SETUP 0x0010 // Setup Packet +#define USB_TXCSRL2_STALL 0x0010 // Send STALL +#define USB_TXCSRL2_FLUSH 0x0008 // Flush FIFO +#define USB_TXCSRL2_ERROR 0x0004 // Error +#define USB_TXCSRL2_UNDRN 0x0004 // Underrun +#define USB_TXCSRL2_FIFONE 0x0002 // FIFO Not Empty +#define USB_TXCSRL2_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRH2 register. // //***************************************************************************** -#define USB_TXCSRH2_AUTOSET 0x00000080 // Auto Set -#define USB_TXCSRH2_ISO 0x00000040 // Isochronous Transfers -#define USB_TXCSRH2_MODE 0x00000020 // Mode -#define USB_TXCSRH2_DMAEN 0x00000010 // DMA Request Enable -#define USB_TXCSRH2_FDT 0x00000008 // Force Data Toggle -#define USB_TXCSRH2_DMAMOD 0x00000004 // DMA Request Mode -#define USB_TXCSRH2_DTWE 0x00000002 // Data Toggle Write Enable -#define USB_TXCSRH2_DT 0x00000001 // Data Toggle +#define USB_TXCSRH2_AUTOSET 0x0080 // Auto Set +#define USB_TXCSRH2_ISO 0x0040 // Isochronous Transfers +#define USB_TXCSRH2_MODE 0x0020 // Mode +#define USB_TXCSRH2_DMAEN 0x0010 // DMA Request Enable +#define USB_TXCSRH2_FDT 0x0008 // Force Data Toggle +#define USB_TXCSRH2_DMAMOD 0x0004 // DMA Request Mode +#define USB_TXCSRH2_DTWE 0x0002 // Data Toggle Write Enable +#define USB_TXCSRH2_DT 0x0001 // Data Toggle //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXMAXP2 register. // //***************************************************************************** -#define USB_RXMAXP2_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP2_MAXLOAD_M 0x07FF // Maximum Payload #define USB_RXMAXP2_MAXLOAD_S 0 //***************************************************************************** @@ -1233,33 +788,33 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCSRL2 register. // //***************************************************************************** -#define USB_RXCSRL2_CLRDT 0x00000080 // Clear Data Toggle -#define USB_RXCSRL2_STALLED 0x00000040 // Endpoint Stalled -#define USB_RXCSRL2_REQPKT 0x00000020 // Request Packet -#define USB_RXCSRL2_STALL 0x00000020 // Send STALL -#define USB_RXCSRL2_FLUSH 0x00000010 // Flush FIFO -#define USB_RXCSRL2_DATAERR 0x00000008 // Data Error -#define USB_RXCSRL2_NAKTO 0x00000008 // NAK Timeout -#define USB_RXCSRL2_ERROR 0x00000004 // Error -#define USB_RXCSRL2_OVER 0x00000004 // Overrun -#define USB_RXCSRL2_FULL 0x00000002 // FIFO Full -#define USB_RXCSRL2_RXRDY 0x00000001 // Receive Packet Ready +#define USB_RXCSRL2_CLRDT 0x0080 // Clear Data Toggle +#define USB_RXCSRL2_STALLED 0x0040 // Endpoint Stalled +#define USB_RXCSRL2_REQPKT 0x0020 // Request Packet +#define USB_RXCSRL2_STALL 0x0020 // Send STALL +#define USB_RXCSRL2_FLUSH 0x0010 // Flush FIFO +#define USB_RXCSRL2_DATAERR 0x0008 // Data Error +#define USB_RXCSRL2_NAKTO 0x0008 // NAK Timeout +#define USB_RXCSRL2_ERROR 0x0004 // Error +#define USB_RXCSRL2_OVER 0x0004 // Overrun +#define USB_RXCSRL2_FULL 0x0002 // FIFO Full +#define USB_RXCSRL2_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRH2 register. // //***************************************************************************** -#define USB_RXCSRH2_AUTOCL 0x00000080 // Auto Clear -#define USB_RXCSRH2_AUTORQ 0x00000040 // Auto Request -#define USB_RXCSRH2_ISO 0x00000040 // Isochronous Transfers -#define USB_RXCSRH2_DMAEN 0x00000020 // DMA Request Enable -#define USB_RXCSRH2_DISNYET 0x00000010 // Disable NYET -#define USB_RXCSRH2_PIDERR 0x00000010 // PID Error -#define USB_RXCSRH2_DMAMOD 0x00000008 // DMA Request Mode -#define USB_RXCSRH2_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_RXCSRH2_DT 0x00000002 // Data Toggle -#define USB_RXCSRH2_INCOMPRX 0x00000001 // Incomplete RX Transmission +#define USB_RXCSRH2_AUTOCL 0x0080 // Auto Clear +#define USB_RXCSRH2_AUTORQ 0x0040 // Auto Request +#define USB_RXCSRH2_ISO 0x0040 // Isochronous Transfers +#define USB_RXCSRH2_DMAEN 0x0020 // DMA Request Enable +#define USB_RXCSRH2_DISNYET 0x0010 // Disable NYET +#define USB_RXCSRH2_PIDERR 0x0010 // PID Error +#define USB_RXCSRH2_DMAMOD 0x0008 // DMA Request Mode +#define USB_RXCSRH2_DTWE 0x0004 // Data Toggle Write Enable +#define USB_RXCSRH2_DT 0x0002 // Data Toggle +#define USB_RXCSRH2_INCOMPRX 0x0001 // Incomplete RX Transmission // Status //***************************************************************************** @@ -1267,7 +822,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCOUNT2 register. // //***************************************************************************** -#define USB_RXCOUNT2_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT2_COUNT_M 0x1FFF // Receive Packet Count #define USB_RXCOUNT2_COUNT_S 0 //***************************************************************************** @@ -1275,17 +830,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXTYPE2 register. // //***************************************************************************** -#define USB_TXTYPE2_SPEED_M 0x000000C0 // Operating Speed -#define USB_TXTYPE2_SPEED_DFLT 0x00000000 // Default -#define USB_TXTYPE2_SPEED_HIGH 0x00000040 // High -#define USB_TXTYPE2_SPEED_FULL 0x00000080 // Full -#define USB_TXTYPE2_SPEED_LOW 0x000000C0 // Low -#define USB_TXTYPE2_PROTO_M 0x00000030 // Protocol -#define USB_TXTYPE2_PROTO_CTRL 0x00000000 // Control -#define USB_TXTYPE2_PROTO_ISOC 0x00000010 // Isochronous -#define USB_TXTYPE2_PROTO_BULK 0x00000020 // Bulk -#define USB_TXTYPE2_PROTO_INT 0x00000030 // Interrupt -#define USB_TXTYPE2_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE2_SPEED_M 0x00C0 // Operating Speed +#define USB_TXTYPE2_SPEED_DFLT 0x0000 // Default +#define USB_TXTYPE2_SPEED_HIGH 0x0040 // High +#define USB_TXTYPE2_SPEED_FULL 0x0080 // Full +#define USB_TXTYPE2_SPEED_LOW 0x00C0 // Low +#define USB_TXTYPE2_PROTO_M 0x0030 // Protocol +#define USB_TXTYPE2_PROTO_CTRL 0x0000 // Control +#define USB_TXTYPE2_PROTO_ISOC 0x0010 // Isochronous +#define USB_TXTYPE2_PROTO_BULK 0x0020 // Bulk +#define USB_TXTYPE2_PROTO_INT 0x0030 // Interrupt +#define USB_TXTYPE2_TEP_M 0x000F // Target Endpoint Number #define USB_TXTYPE2_TEP_S 0 //***************************************************************************** @@ -1294,31 +849,27 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXINTERVAL2_TXPOLL_M \ - 0x000000FF // TX Polling -#define USB_TXINTERVAL2_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_TXINTERVAL2_NAKLMT_S \ - 0 -#define USB_TXINTERVAL2_TXPOLL_S \ - 0 +#define USB_TXINTERVAL2_TXPOLL_M 0x00FF // TX Polling +#define USB_TXINTERVAL2_NAKLMT_M 0x00FF // NAK Limit +#define USB_TXINTERVAL2_NAKLMT_S 0 +#define USB_TXINTERVAL2_TXPOLL_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXTYPE2 register. // //***************************************************************************** -#define USB_RXTYPE2_SPEED_M 0x000000C0 // Operating Speed -#define USB_RXTYPE2_SPEED_DFLT 0x00000000 // Default -#define USB_RXTYPE2_SPEED_HIGH 0x00000040 // High -#define USB_RXTYPE2_SPEED_FULL 0x00000080 // Full -#define USB_RXTYPE2_SPEED_LOW 0x000000C0 // Low -#define USB_RXTYPE2_PROTO_M 0x00000030 // Protocol -#define USB_RXTYPE2_PROTO_CTRL 0x00000000 // Control -#define USB_RXTYPE2_PROTO_ISOC 0x00000010 // Isochronous -#define USB_RXTYPE2_PROTO_BULK 0x00000020 // Bulk -#define USB_RXTYPE2_PROTO_INT 0x00000030 // Interrupt -#define USB_RXTYPE2_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE2_SPEED_M 0x00C0 // Operating Speed +#define USB_RXTYPE2_SPEED_DFLT 0x0000 // Default +#define USB_RXTYPE2_SPEED_HIGH 0x0040 // High +#define USB_RXTYPE2_SPEED_FULL 0x0080 // Full +#define USB_RXTYPE2_SPEED_LOW 0x00C0 // Low +#define USB_RXTYPE2_PROTO_M 0x0030 // Protocol +#define USB_RXTYPE2_PROTO_CTRL 0x0000 // Control +#define USB_RXTYPE2_PROTO_ISOC 0x0010 // Isochronous +#define USB_RXTYPE2_PROTO_BULK 0x0020 // Bulk +#define USB_RXTYPE2_PROTO_INT 0x0030 // Interrupt +#define USB_RXTYPE2_TEP_M 0x000F // Target Endpoint Number #define USB_RXTYPE2_TEP_S 0 //***************************************************************************** @@ -1327,21 +878,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXINTERVAL2_TXPOLL_M \ - 0x000000FF // RX Polling -#define USB_RXINTERVAL2_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_RXINTERVAL2_TXPOLL_S \ - 0 -#define USB_RXINTERVAL2_NAKLMT_S \ - 0 +#define USB_RXINTERVAL2_TXPOLL_M 0x00FF // RX Polling +#define USB_RXINTERVAL2_NAKLMT_M 0x00FF // NAK Limit +#define USB_RXINTERVAL2_TXPOLL_S 0 +#define USB_RXINTERVAL2_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXMAXP3 register. // //***************************************************************************** -#define USB_TXMAXP3_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP3_MAXLOAD_M 0x07FF // Maximum Payload #define USB_TXMAXP3_MAXLOAD_S 0 //***************************************************************************** @@ -1349,37 +896,37 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXCSRL3 register. // //***************************************************************************** -#define USB_TXCSRL3_NAKTO 0x00000080 // NAK Timeout -#define USB_TXCSRL3_CLRDT 0x00000040 // Clear Data Toggle -#define USB_TXCSRL3_STALLED 0x00000020 // Endpoint Stalled -#define USB_TXCSRL3_SETUP 0x00000010 // Setup Packet -#define USB_TXCSRL3_STALL 0x00000010 // Send STALL -#define USB_TXCSRL3_FLUSH 0x00000008 // Flush FIFO -#define USB_TXCSRL3_ERROR 0x00000004 // Error -#define USB_TXCSRL3_UNDRN 0x00000004 // Underrun -#define USB_TXCSRL3_FIFONE 0x00000002 // FIFO Not Empty -#define USB_TXCSRL3_TXRDY 0x00000001 // Transmit Packet Ready +#define USB_TXCSRL3_NAKTO 0x0080 // NAK Timeout +#define USB_TXCSRL3_CLRDT 0x0040 // Clear Data Toggle +#define USB_TXCSRL3_STALLED 0x0020 // Endpoint Stalled +#define USB_TXCSRL3_SETUP 0x0010 // Setup Packet +#define USB_TXCSRL3_STALL 0x0010 // Send STALL +#define USB_TXCSRL3_FLUSH 0x0008 // Flush FIFO +#define USB_TXCSRL3_ERROR 0x0004 // Error +#define USB_TXCSRL3_UNDRN 0x0004 // Underrun +#define USB_TXCSRL3_FIFONE 0x0002 // FIFO Not Empty +#define USB_TXCSRL3_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRH3 register. // //***************************************************************************** -#define USB_TXCSRH3_AUTOSET 0x00000080 // Auto Set -#define USB_TXCSRH3_ISO 0x00000040 // Isochronous Transfers -#define USB_TXCSRH3_MODE 0x00000020 // Mode -#define USB_TXCSRH3_DMAEN 0x00000010 // DMA Request Enable -#define USB_TXCSRH3_FDT 0x00000008 // Force Data Toggle -#define USB_TXCSRH3_DMAMOD 0x00000004 // DMA Request Mode -#define USB_TXCSRH3_DTWE 0x00000002 // Data Toggle Write Enable -#define USB_TXCSRH3_DT 0x00000001 // Data Toggle +#define USB_TXCSRH3_AUTOSET 0x0080 // Auto Set +#define USB_TXCSRH3_ISO 0x0040 // Isochronous Transfers +#define USB_TXCSRH3_MODE 0x0020 // Mode +#define USB_TXCSRH3_DMAEN 0x0010 // DMA Request Enable +#define USB_TXCSRH3_FDT 0x0008 // Force Data Toggle +#define USB_TXCSRH3_DMAMOD 0x0004 // DMA Request Mode +#define USB_TXCSRH3_DTWE 0x0002 // Data Toggle Write Enable +#define USB_TXCSRH3_DT 0x0001 // Data Toggle //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXMAXP3 register. // //***************************************************************************** -#define USB_RXMAXP3_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP3_MAXLOAD_M 0x07FF // Maximum Payload #define USB_RXMAXP3_MAXLOAD_S 0 //***************************************************************************** @@ -1387,33 +934,33 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCSRL3 register. // //***************************************************************************** -#define USB_RXCSRL3_CLRDT 0x00000080 // Clear Data Toggle -#define USB_RXCSRL3_STALLED 0x00000040 // Endpoint Stalled -#define USB_RXCSRL3_STALL 0x00000020 // Send STALL -#define USB_RXCSRL3_REQPKT 0x00000020 // Request Packet -#define USB_RXCSRL3_FLUSH 0x00000010 // Flush FIFO -#define USB_RXCSRL3_DATAERR 0x00000008 // Data Error -#define USB_RXCSRL3_NAKTO 0x00000008 // NAK Timeout -#define USB_RXCSRL3_ERROR 0x00000004 // Error -#define USB_RXCSRL3_OVER 0x00000004 // Overrun -#define USB_RXCSRL3_FULL 0x00000002 // FIFO Full -#define USB_RXCSRL3_RXRDY 0x00000001 // Receive Packet Ready +#define USB_RXCSRL3_CLRDT 0x0080 // Clear Data Toggle +#define USB_RXCSRL3_STALLED 0x0040 // Endpoint Stalled +#define USB_RXCSRL3_STALL 0x0020 // Send STALL +#define USB_RXCSRL3_REQPKT 0x0020 // Request Packet +#define USB_RXCSRL3_FLUSH 0x0010 // Flush FIFO +#define USB_RXCSRL3_DATAERR 0x0008 // Data Error +#define USB_RXCSRL3_NAKTO 0x0008 // NAK Timeout +#define USB_RXCSRL3_ERROR 0x0004 // Error +#define USB_RXCSRL3_OVER 0x0004 // Overrun +#define USB_RXCSRL3_FULL 0x0002 // FIFO Full +#define USB_RXCSRL3_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRH3 register. // //***************************************************************************** -#define USB_RXCSRH3_AUTOCL 0x00000080 // Auto Clear -#define USB_RXCSRH3_AUTORQ 0x00000040 // Auto Request -#define USB_RXCSRH3_ISO 0x00000040 // Isochronous Transfers -#define USB_RXCSRH3_DMAEN 0x00000020 // DMA Request Enable -#define USB_RXCSRH3_DISNYET 0x00000010 // Disable NYET -#define USB_RXCSRH3_PIDERR 0x00000010 // PID Error -#define USB_RXCSRH3_DMAMOD 0x00000008 // DMA Request Mode -#define USB_RXCSRH3_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_RXCSRH3_DT 0x00000002 // Data Toggle -#define USB_RXCSRH3_INCOMPRX 0x00000001 // Incomplete RX Transmission +#define USB_RXCSRH3_AUTOCL 0x0080 // Auto Clear +#define USB_RXCSRH3_AUTORQ 0x0040 // Auto Request +#define USB_RXCSRH3_ISO 0x0040 // Isochronous Transfers +#define USB_RXCSRH3_DMAEN 0x0020 // DMA Request Enable +#define USB_RXCSRH3_DISNYET 0x0010 // Disable NYET +#define USB_RXCSRH3_PIDERR 0x0010 // PID Error +#define USB_RXCSRH3_DMAMOD 0x0008 // DMA Request Mode +#define USB_RXCSRH3_DTWE 0x0004 // Data Toggle Write Enable +#define USB_RXCSRH3_DT 0x0002 // Data Toggle +#define USB_RXCSRH3_INCOMPRX 0x0001 // Incomplete RX Transmission // Status //***************************************************************************** @@ -1421,7 +968,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCOUNT3 register. // //***************************************************************************** -#define USB_RXCOUNT3_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT3_COUNT_M 0x1FFF // Receive Packet Count #define USB_RXCOUNT3_COUNT_S 0 //***************************************************************************** @@ -1429,17 +976,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXTYPE3 register. // //***************************************************************************** -#define USB_TXTYPE3_SPEED_M 0x000000C0 // Operating Speed -#define USB_TXTYPE3_SPEED_DFLT 0x00000000 // Default -#define USB_TXTYPE3_SPEED_HIGH 0x00000040 // High -#define USB_TXTYPE3_SPEED_FULL 0x00000080 // Full -#define USB_TXTYPE3_SPEED_LOW 0x000000C0 // Low -#define USB_TXTYPE3_PROTO_M 0x00000030 // Protocol -#define USB_TXTYPE3_PROTO_CTRL 0x00000000 // Control -#define USB_TXTYPE3_PROTO_ISOC 0x00000010 // Isochronous -#define USB_TXTYPE3_PROTO_BULK 0x00000020 // Bulk -#define USB_TXTYPE3_PROTO_INT 0x00000030 // Interrupt -#define USB_TXTYPE3_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE3_SPEED_M 0x00C0 // Operating Speed +#define USB_TXTYPE3_SPEED_DFLT 0x0000 // Default +#define USB_TXTYPE3_SPEED_HIGH 0x0040 // High +#define USB_TXTYPE3_SPEED_FULL 0x0080 // Full +#define USB_TXTYPE3_SPEED_LOW 0x00C0 // Low +#define USB_TXTYPE3_PROTO_M 0x0030 // Protocol +#define USB_TXTYPE3_PROTO_CTRL 0x0000 // Control +#define USB_TXTYPE3_PROTO_ISOC 0x0010 // Isochronous +#define USB_TXTYPE3_PROTO_BULK 0x0020 // Bulk +#define USB_TXTYPE3_PROTO_INT 0x0030 // Interrupt +#define USB_TXTYPE3_TEP_M 0x000F // Target Endpoint Number #define USB_TXTYPE3_TEP_S 0 //***************************************************************************** @@ -1448,31 +995,27 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXINTERVAL3_TXPOLL_M \ - 0x000000FF // TX Polling -#define USB_TXINTERVAL3_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_TXINTERVAL3_TXPOLL_S \ - 0 -#define USB_TXINTERVAL3_NAKLMT_S \ - 0 +#define USB_TXINTERVAL3_TXPOLL_M 0x00FF // TX Polling +#define USB_TXINTERVAL3_NAKLMT_M 0x00FF // NAK Limit +#define USB_TXINTERVAL3_TXPOLL_S 0 +#define USB_TXINTERVAL3_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXTYPE3 register. // //***************************************************************************** -#define USB_RXTYPE3_SPEED_M 0x000000C0 // Operating Speed -#define USB_RXTYPE3_SPEED_DFLT 0x00000000 // Default -#define USB_RXTYPE3_SPEED_HIGH 0x00000040 // High -#define USB_RXTYPE3_SPEED_FULL 0x00000080 // Full -#define USB_RXTYPE3_SPEED_LOW 0x000000C0 // Low -#define USB_RXTYPE3_PROTO_M 0x00000030 // Protocol -#define USB_RXTYPE3_PROTO_CTRL 0x00000000 // Control -#define USB_RXTYPE3_PROTO_ISOC 0x00000010 // Isochronous -#define USB_RXTYPE3_PROTO_BULK 0x00000020 // Bulk -#define USB_RXTYPE3_PROTO_INT 0x00000030 // Interrupt -#define USB_RXTYPE3_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE3_SPEED_M 0x00C0 // Operating Speed +#define USB_RXTYPE3_SPEED_DFLT 0x0000 // Default +#define USB_RXTYPE3_SPEED_HIGH 0x0040 // High +#define USB_RXTYPE3_SPEED_FULL 0x0080 // Full +#define USB_RXTYPE3_SPEED_LOW 0x00C0 // Low +#define USB_RXTYPE3_PROTO_M 0x0030 // Protocol +#define USB_RXTYPE3_PROTO_CTRL 0x0000 // Control +#define USB_RXTYPE3_PROTO_ISOC 0x0010 // Isochronous +#define USB_RXTYPE3_PROTO_BULK 0x0020 // Bulk +#define USB_RXTYPE3_PROTO_INT 0x0030 // Interrupt +#define USB_RXTYPE3_TEP_M 0x000F // Target Endpoint Number #define USB_RXTYPE3_TEP_S 0 //***************************************************************************** @@ -1481,21 +1024,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXINTERVAL3_TXPOLL_M \ - 0x000000FF // RX Polling -#define USB_RXINTERVAL3_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_RXINTERVAL3_TXPOLL_S \ - 0 -#define USB_RXINTERVAL3_NAKLMT_S \ - 0 +#define USB_RXINTERVAL3_TXPOLL_M 0x00FF // RX Polling +#define USB_RXINTERVAL3_NAKLMT_M 0x00FF // NAK Limit +#define USB_RXINTERVAL3_TXPOLL_S 0 +#define USB_RXINTERVAL3_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXMAXP4 register. // //***************************************************************************** -#define USB_TXMAXP4_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP4_MAXLOAD_M 0x07FF // Maximum Payload #define USB_TXMAXP4_MAXLOAD_S 0 //***************************************************************************** @@ -1503,37 +1042,37 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXCSRL4 register. // //***************************************************************************** -#define USB_TXCSRL4_NAKTO 0x00000080 // NAK Timeout -#define USB_TXCSRL4_CLRDT 0x00000040 // Clear Data Toggle -#define USB_TXCSRL4_STALLED 0x00000020 // Endpoint Stalled -#define USB_TXCSRL4_SETUP 0x00000010 // Setup Packet -#define USB_TXCSRL4_STALL 0x00000010 // Send STALL -#define USB_TXCSRL4_FLUSH 0x00000008 // Flush FIFO -#define USB_TXCSRL4_ERROR 0x00000004 // Error -#define USB_TXCSRL4_UNDRN 0x00000004 // Underrun -#define USB_TXCSRL4_FIFONE 0x00000002 // FIFO Not Empty -#define USB_TXCSRL4_TXRDY 0x00000001 // Transmit Packet Ready +#define USB_TXCSRL4_NAKTO 0x0080 // NAK Timeout +#define USB_TXCSRL4_CLRDT 0x0040 // Clear Data Toggle +#define USB_TXCSRL4_STALLED 0x0020 // Endpoint Stalled +#define USB_TXCSRL4_SETUP 0x0010 // Setup Packet +#define USB_TXCSRL4_STALL 0x0010 // Send STALL +#define USB_TXCSRL4_FLUSH 0x0008 // Flush FIFO +#define USB_TXCSRL4_ERROR 0x0004 // Error +#define USB_TXCSRL4_UNDRN 0x0004 // Underrun +#define USB_TXCSRL4_FIFONE 0x0002 // FIFO Not Empty +#define USB_TXCSRL4_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRH4 register. // //***************************************************************************** -#define USB_TXCSRH4_AUTOSET 0x00000080 // Auto Set -#define USB_TXCSRH4_ISO 0x00000040 // Isochronous Transfers -#define USB_TXCSRH4_MODE 0x00000020 // Mode -#define USB_TXCSRH4_DMAEN 0x00000010 // DMA Request Enable -#define USB_TXCSRH4_FDT 0x00000008 // Force Data Toggle -#define USB_TXCSRH4_DMAMOD 0x00000004 // DMA Request Mode -#define USB_TXCSRH4_DTWE 0x00000002 // Data Toggle Write Enable -#define USB_TXCSRH4_DT 0x00000001 // Data Toggle +#define USB_TXCSRH4_AUTOSET 0x0080 // Auto Set +#define USB_TXCSRH4_ISO 0x0040 // Isochronous Transfers +#define USB_TXCSRH4_MODE 0x0020 // Mode +#define USB_TXCSRH4_DMAEN 0x0010 // DMA Request Enable +#define USB_TXCSRH4_FDT 0x0008 // Force Data Toggle +#define USB_TXCSRH4_DMAMOD 0x0004 // DMA Request Mode +#define USB_TXCSRH4_DTWE 0x0002 // Data Toggle Write Enable +#define USB_TXCSRH4_DT 0x0001 // Data Toggle //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXMAXP4 register. // //***************************************************************************** -#define USB_RXMAXP4_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP4_MAXLOAD_M 0x07FF // Maximum Payload #define USB_RXMAXP4_MAXLOAD_S 0 //***************************************************************************** @@ -1541,33 +1080,33 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCSRL4 register. // //***************************************************************************** -#define USB_RXCSRL4_CLRDT 0x00000080 // Clear Data Toggle -#define USB_RXCSRL4_STALLED 0x00000040 // Endpoint Stalled -#define USB_RXCSRL4_STALL 0x00000020 // Send STALL -#define USB_RXCSRL4_REQPKT 0x00000020 // Request Packet -#define USB_RXCSRL4_FLUSH 0x00000010 // Flush FIFO -#define USB_RXCSRL4_NAKTO 0x00000008 // NAK Timeout -#define USB_RXCSRL4_DATAERR 0x00000008 // Data Error -#define USB_RXCSRL4_OVER 0x00000004 // Overrun -#define USB_RXCSRL4_ERROR 0x00000004 // Error -#define USB_RXCSRL4_FULL 0x00000002 // FIFO Full -#define USB_RXCSRL4_RXRDY 0x00000001 // Receive Packet Ready +#define USB_RXCSRL4_CLRDT 0x0080 // Clear Data Toggle +#define USB_RXCSRL4_STALLED 0x0040 // Endpoint Stalled +#define USB_RXCSRL4_STALL 0x0020 // Send STALL +#define USB_RXCSRL4_REQPKT 0x0020 // Request Packet +#define USB_RXCSRL4_FLUSH 0x0010 // Flush FIFO +#define USB_RXCSRL4_NAKTO 0x0008 // NAK Timeout +#define USB_RXCSRL4_DATAERR 0x0008 // Data Error +#define USB_RXCSRL4_OVER 0x0004 // Overrun +#define USB_RXCSRL4_ERROR 0x0004 // Error +#define USB_RXCSRL4_FULL 0x0002 // FIFO Full +#define USB_RXCSRL4_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRH4 register. // //***************************************************************************** -#define USB_RXCSRH4_AUTOCL 0x00000080 // Auto Clear -#define USB_RXCSRH4_AUTORQ 0x00000040 // Auto Request -#define USB_RXCSRH4_ISO 0x00000040 // Isochronous Transfers -#define USB_RXCSRH4_DMAEN 0x00000020 // DMA Request Enable -#define USB_RXCSRH4_DISNYET 0x00000010 // Disable NYET -#define USB_RXCSRH4_PIDERR 0x00000010 // PID Error -#define USB_RXCSRH4_DMAMOD 0x00000008 // DMA Request Mode -#define USB_RXCSRH4_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_RXCSRH4_DT 0x00000002 // Data Toggle -#define USB_RXCSRH4_INCOMPRX 0x00000001 // Incomplete RX Transmission +#define USB_RXCSRH4_AUTOCL 0x0080 // Auto Clear +#define USB_RXCSRH4_AUTORQ 0x0040 // Auto Request +#define USB_RXCSRH4_ISO 0x0040 // Isochronous Transfers +#define USB_RXCSRH4_DMAEN 0x0020 // DMA Request Enable +#define USB_RXCSRH4_DISNYET 0x0010 // Disable NYET +#define USB_RXCSRH4_PIDERR 0x0010 // PID Error +#define USB_RXCSRH4_DMAMOD 0x0008 // DMA Request Mode +#define USB_RXCSRH4_DTWE 0x0004 // Data Toggle Write Enable +#define USB_RXCSRH4_DT 0x0002 // Data Toggle +#define USB_RXCSRH4_INCOMPRX 0x0001 // Incomplete RX Transmission // Status //***************************************************************************** @@ -1575,7 +1114,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCOUNT4 register. // //***************************************************************************** -#define USB_RXCOUNT4_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT4_COUNT_M 0x1FFF // Receive Packet Count #define USB_RXCOUNT4_COUNT_S 0 //***************************************************************************** @@ -1583,17 +1122,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXTYPE4 register. // //***************************************************************************** -#define USB_TXTYPE4_SPEED_M 0x000000C0 // Operating Speed -#define USB_TXTYPE4_SPEED_DFLT 0x00000000 // Default -#define USB_TXTYPE4_SPEED_HIGH 0x00000040 // High -#define USB_TXTYPE4_SPEED_FULL 0x00000080 // Full -#define USB_TXTYPE4_SPEED_LOW 0x000000C0 // Low -#define USB_TXTYPE4_PROTO_M 0x00000030 // Protocol -#define USB_TXTYPE4_PROTO_CTRL 0x00000000 // Control -#define USB_TXTYPE4_PROTO_ISOC 0x00000010 // Isochronous -#define USB_TXTYPE4_PROTO_BULK 0x00000020 // Bulk -#define USB_TXTYPE4_PROTO_INT 0x00000030 // Interrupt -#define USB_TXTYPE4_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE4_SPEED_M 0x00C0 // Operating Speed +#define USB_TXTYPE4_SPEED_DFLT 0x0000 // Default +#define USB_TXTYPE4_SPEED_HIGH 0x0040 // High +#define USB_TXTYPE4_SPEED_FULL 0x0080 // Full +#define USB_TXTYPE4_SPEED_LOW 0x00C0 // Low +#define USB_TXTYPE4_PROTO_M 0x0030 // Protocol +#define USB_TXTYPE4_PROTO_CTRL 0x0000 // Control +#define USB_TXTYPE4_PROTO_ISOC 0x0010 // Isochronous +#define USB_TXTYPE4_PROTO_BULK 0x0020 // Bulk +#define USB_TXTYPE4_PROTO_INT 0x0030 // Interrupt +#define USB_TXTYPE4_TEP_M 0x000F // Target Endpoint Number #define USB_TXTYPE4_TEP_S 0 //***************************************************************************** @@ -1602,31 +1141,27 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXINTERVAL4_TXPOLL_M \ - 0x000000FF // TX Polling -#define USB_TXINTERVAL4_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_TXINTERVAL4_NAKLMT_S \ - 0 -#define USB_TXINTERVAL4_TXPOLL_S \ - 0 +#define USB_TXINTERVAL4_TXPOLL_M 0x00FF // TX Polling +#define USB_TXINTERVAL4_NAKLMT_M 0x00FF // NAK Limit +#define USB_TXINTERVAL4_NAKLMT_S 0 +#define USB_TXINTERVAL4_TXPOLL_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXTYPE4 register. // //***************************************************************************** -#define USB_RXTYPE4_SPEED_M 0x000000C0 // Operating Speed -#define USB_RXTYPE4_SPEED_DFLT 0x00000000 // Default -#define USB_RXTYPE4_SPEED_HIGH 0x00000040 // High -#define USB_RXTYPE4_SPEED_FULL 0x00000080 // Full -#define USB_RXTYPE4_SPEED_LOW 0x000000C0 // Low -#define USB_RXTYPE4_PROTO_M 0x00000030 // Protocol -#define USB_RXTYPE4_PROTO_CTRL 0x00000000 // Control -#define USB_RXTYPE4_PROTO_ISOC 0x00000010 // Isochronous -#define USB_RXTYPE4_PROTO_BULK 0x00000020 // Bulk -#define USB_RXTYPE4_PROTO_INT 0x00000030 // Interrupt -#define USB_RXTYPE4_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE4_SPEED_M 0x00C0 // Operating Speed +#define USB_RXTYPE4_SPEED_DFLT 0x0000 // Default +#define USB_RXTYPE4_SPEED_HIGH 0x0040 // High +#define USB_RXTYPE4_SPEED_FULL 0x0080 // Full +#define USB_RXTYPE4_SPEED_LOW 0x00C0 // Low +#define USB_RXTYPE4_PROTO_M 0x0030 // Protocol +#define USB_RXTYPE4_PROTO_CTRL 0x0000 // Control +#define USB_RXTYPE4_PROTO_ISOC 0x0010 // Isochronous +#define USB_RXTYPE4_PROTO_BULK 0x0020 // Bulk +#define USB_RXTYPE4_PROTO_INT 0x0030 // Interrupt +#define USB_RXTYPE4_TEP_M 0x000F // Target Endpoint Number #define USB_RXTYPE4_TEP_S 0 //***************************************************************************** @@ -1635,21 +1170,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXINTERVAL4_TXPOLL_M \ - 0x000000FF // RX Polling -#define USB_RXINTERVAL4_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_RXINTERVAL4_NAKLMT_S \ - 0 -#define USB_RXINTERVAL4_TXPOLL_S \ - 0 +#define USB_RXINTERVAL4_TXPOLL_M 0x00FF // RX Polling +#define USB_RXINTERVAL4_NAKLMT_M 0x00FF // NAK Limit +#define USB_RXINTERVAL4_NAKLMT_S 0 +#define USB_RXINTERVAL4_TXPOLL_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXMAXP5 register. // //***************************************************************************** -#define USB_TXMAXP5_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP5_MAXLOAD_M 0x07FF // Maximum Payload #define USB_TXMAXP5_MAXLOAD_S 0 //***************************************************************************** @@ -1657,37 +1188,37 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXCSRL5 register. // //***************************************************************************** -#define USB_TXCSRL5_NAKTO 0x00000080 // NAK Timeout -#define USB_TXCSRL5_CLRDT 0x00000040 // Clear Data Toggle -#define USB_TXCSRL5_STALLED 0x00000020 // Endpoint Stalled -#define USB_TXCSRL5_SETUP 0x00000010 // Setup Packet -#define USB_TXCSRL5_STALL 0x00000010 // Send STALL -#define USB_TXCSRL5_FLUSH 0x00000008 // Flush FIFO -#define USB_TXCSRL5_ERROR 0x00000004 // Error -#define USB_TXCSRL5_UNDRN 0x00000004 // Underrun -#define USB_TXCSRL5_FIFONE 0x00000002 // FIFO Not Empty -#define USB_TXCSRL5_TXRDY 0x00000001 // Transmit Packet Ready +#define USB_TXCSRL5_NAKTO 0x0080 // NAK Timeout +#define USB_TXCSRL5_CLRDT 0x0040 // Clear Data Toggle +#define USB_TXCSRL5_STALLED 0x0020 // Endpoint Stalled +#define USB_TXCSRL5_SETUP 0x0010 // Setup Packet +#define USB_TXCSRL5_STALL 0x0010 // Send STALL +#define USB_TXCSRL5_FLUSH 0x0008 // Flush FIFO +#define USB_TXCSRL5_ERROR 0x0004 // Error +#define USB_TXCSRL5_UNDRN 0x0004 // Underrun +#define USB_TXCSRL5_FIFONE 0x0002 // FIFO Not Empty +#define USB_TXCSRL5_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRH5 register. // //***************************************************************************** -#define USB_TXCSRH5_AUTOSET 0x00000080 // Auto Set -#define USB_TXCSRH5_ISO 0x00000040 // Isochronous Transfers -#define USB_TXCSRH5_MODE 0x00000020 // Mode -#define USB_TXCSRH5_DMAEN 0x00000010 // DMA Request Enable -#define USB_TXCSRH5_FDT 0x00000008 // Force Data Toggle -#define USB_TXCSRH5_DMAMOD 0x00000004 // DMA Request Mode -#define USB_TXCSRH5_DTWE 0x00000002 // Data Toggle Write Enable -#define USB_TXCSRH5_DT 0x00000001 // Data Toggle +#define USB_TXCSRH5_AUTOSET 0x0080 // Auto Set +#define USB_TXCSRH5_ISO 0x0040 // Isochronous Transfers +#define USB_TXCSRH5_MODE 0x0020 // Mode +#define USB_TXCSRH5_DMAEN 0x0010 // DMA Request Enable +#define USB_TXCSRH5_FDT 0x0008 // Force Data Toggle +#define USB_TXCSRH5_DMAMOD 0x0004 // DMA Request Mode +#define USB_TXCSRH5_DTWE 0x0002 // Data Toggle Write Enable +#define USB_TXCSRH5_DT 0x0001 // Data Toggle //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXMAXP5 register. // //***************************************************************************** -#define USB_RXMAXP5_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP5_MAXLOAD_M 0x07FF // Maximum Payload #define USB_RXMAXP5_MAXLOAD_S 0 //***************************************************************************** @@ -1695,33 +1226,33 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCSRL5 register. // //***************************************************************************** -#define USB_RXCSRL5_CLRDT 0x00000080 // Clear Data Toggle -#define USB_RXCSRL5_STALLED 0x00000040 // Endpoint Stalled -#define USB_RXCSRL5_STALL 0x00000020 // Send STALL -#define USB_RXCSRL5_REQPKT 0x00000020 // Request Packet -#define USB_RXCSRL5_FLUSH 0x00000010 // Flush FIFO -#define USB_RXCSRL5_NAKTO 0x00000008 // NAK Timeout -#define USB_RXCSRL5_DATAERR 0x00000008 // Data Error -#define USB_RXCSRL5_ERROR 0x00000004 // Error -#define USB_RXCSRL5_OVER 0x00000004 // Overrun -#define USB_RXCSRL5_FULL 0x00000002 // FIFO Full -#define USB_RXCSRL5_RXRDY 0x00000001 // Receive Packet Ready +#define USB_RXCSRL5_CLRDT 0x0080 // Clear Data Toggle +#define USB_RXCSRL5_STALLED 0x0040 // Endpoint Stalled +#define USB_RXCSRL5_STALL 0x0020 // Send STALL +#define USB_RXCSRL5_REQPKT 0x0020 // Request Packet +#define USB_RXCSRL5_FLUSH 0x0010 // Flush FIFO +#define USB_RXCSRL5_NAKTO 0x0008 // NAK Timeout +#define USB_RXCSRL5_DATAERR 0x0008 // Data Error +#define USB_RXCSRL5_ERROR 0x0004 // Error +#define USB_RXCSRL5_OVER 0x0004 // Overrun +#define USB_RXCSRL5_FULL 0x0002 // FIFO Full +#define USB_RXCSRL5_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRH5 register. // //***************************************************************************** -#define USB_RXCSRH5_AUTOCL 0x00000080 // Auto Clear -#define USB_RXCSRH5_AUTORQ 0x00000040 // Auto Request -#define USB_RXCSRH5_ISO 0x00000040 // Isochronous Transfers -#define USB_RXCSRH5_DMAEN 0x00000020 // DMA Request Enable -#define USB_RXCSRH5_DISNYET 0x00000010 // Disable NYET -#define USB_RXCSRH5_PIDERR 0x00000010 // PID Error -#define USB_RXCSRH5_DMAMOD 0x00000008 // DMA Request Mode -#define USB_RXCSRH5_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_RXCSRH5_DT 0x00000002 // Data Toggle -#define USB_RXCSRH5_INCOMPRX 0x00000001 // Incomplete RX Transmission +#define USB_RXCSRH5_AUTOCL 0x0080 // Auto Clear +#define USB_RXCSRH5_AUTORQ 0x0040 // Auto Request +#define USB_RXCSRH5_ISO 0x0040 // Isochronous Transfers +#define USB_RXCSRH5_DMAEN 0x0020 // DMA Request Enable +#define USB_RXCSRH5_DISNYET 0x0010 // Disable NYET +#define USB_RXCSRH5_PIDERR 0x0010 // PID Error +#define USB_RXCSRH5_DMAMOD 0x0008 // DMA Request Mode +#define USB_RXCSRH5_DTWE 0x0004 // Data Toggle Write Enable +#define USB_RXCSRH5_DT 0x0002 // Data Toggle +#define USB_RXCSRH5_INCOMPRX 0x0001 // Incomplete RX Transmission // Status //***************************************************************************** @@ -1729,7 +1260,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCOUNT5 register. // //***************************************************************************** -#define USB_RXCOUNT5_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT5_COUNT_M 0x1FFF // Receive Packet Count #define USB_RXCOUNT5_COUNT_S 0 //***************************************************************************** @@ -1737,17 +1268,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXTYPE5 register. // //***************************************************************************** -#define USB_TXTYPE5_SPEED_M 0x000000C0 // Operating Speed -#define USB_TXTYPE5_SPEED_DFLT 0x00000000 // Default -#define USB_TXTYPE5_SPEED_HIGH 0x00000040 // High -#define USB_TXTYPE5_SPEED_FULL 0x00000080 // Full -#define USB_TXTYPE5_SPEED_LOW 0x000000C0 // Low -#define USB_TXTYPE5_PROTO_M 0x00000030 // Protocol -#define USB_TXTYPE5_PROTO_CTRL 0x00000000 // Control -#define USB_TXTYPE5_PROTO_ISOC 0x00000010 // Isochronous -#define USB_TXTYPE5_PROTO_BULK 0x00000020 // Bulk -#define USB_TXTYPE5_PROTO_INT 0x00000030 // Interrupt -#define USB_TXTYPE5_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE5_SPEED_M 0x00C0 // Operating Speed +#define USB_TXTYPE5_SPEED_DFLT 0x0000 // Default +#define USB_TXTYPE5_SPEED_HIGH 0x0040 // High +#define USB_TXTYPE5_SPEED_FULL 0x0080 // Full +#define USB_TXTYPE5_SPEED_LOW 0x00C0 // Low +#define USB_TXTYPE5_PROTO_M 0x0030 // Protocol +#define USB_TXTYPE5_PROTO_CTRL 0x0000 // Control +#define USB_TXTYPE5_PROTO_ISOC 0x0010 // Isochronous +#define USB_TXTYPE5_PROTO_BULK 0x0020 // Bulk +#define USB_TXTYPE5_PROTO_INT 0x0030 // Interrupt +#define USB_TXTYPE5_TEP_M 0x000F // Target Endpoint Number #define USB_TXTYPE5_TEP_S 0 //***************************************************************************** @@ -1756,31 +1287,27 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXINTERVAL5_TXPOLL_M \ - 0x000000FF // TX Polling -#define USB_TXINTERVAL5_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_TXINTERVAL5_NAKLMT_S \ - 0 -#define USB_TXINTERVAL5_TXPOLL_S \ - 0 +#define USB_TXINTERVAL5_TXPOLL_M 0x00FF // TX Polling +#define USB_TXINTERVAL5_NAKLMT_M 0x00FF // NAK Limit +#define USB_TXINTERVAL5_NAKLMT_S 0 +#define USB_TXINTERVAL5_TXPOLL_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXTYPE5 register. // //***************************************************************************** -#define USB_RXTYPE5_SPEED_M 0x000000C0 // Operating Speed -#define USB_RXTYPE5_SPEED_DFLT 0x00000000 // Default -#define USB_RXTYPE5_SPEED_HIGH 0x00000040 // High -#define USB_RXTYPE5_SPEED_FULL 0x00000080 // Full -#define USB_RXTYPE5_SPEED_LOW 0x000000C0 // Low -#define USB_RXTYPE5_PROTO_M 0x00000030 // Protocol -#define USB_RXTYPE5_PROTO_CTRL 0x00000000 // Control -#define USB_RXTYPE5_PROTO_ISOC 0x00000010 // Isochronous -#define USB_RXTYPE5_PROTO_BULK 0x00000020 // Bulk -#define USB_RXTYPE5_PROTO_INT 0x00000030 // Interrupt -#define USB_RXTYPE5_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE5_SPEED_M 0x00C0 // Operating Speed +#define USB_RXTYPE5_SPEED_DFLT 0x0000 // Default +#define USB_RXTYPE5_SPEED_HIGH 0x0040 // High +#define USB_RXTYPE5_SPEED_FULL 0x0080 // Full +#define USB_RXTYPE5_SPEED_LOW 0x00C0 // Low +#define USB_RXTYPE5_PROTO_M 0x0030 // Protocol +#define USB_RXTYPE5_PROTO_CTRL 0x0000 // Control +#define USB_RXTYPE5_PROTO_ISOC 0x0010 // Isochronous +#define USB_RXTYPE5_PROTO_BULK 0x0020 // Bulk +#define USB_RXTYPE5_PROTO_INT 0x0030 // Interrupt +#define USB_RXTYPE5_TEP_M 0x000F // Target Endpoint Number #define USB_RXTYPE5_TEP_S 0 //***************************************************************************** @@ -1789,21 +1316,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXINTERVAL5_TXPOLL_M \ - 0x000000FF // RX Polling -#define USB_RXINTERVAL5_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_RXINTERVAL5_TXPOLL_S \ - 0 -#define USB_RXINTERVAL5_NAKLMT_S \ - 0 +#define USB_RXINTERVAL5_TXPOLL_M 0x00FF // RX Polling +#define USB_RXINTERVAL5_NAKLMT_M 0x00FF // NAK Limit +#define USB_RXINTERVAL5_TXPOLL_S 0 +#define USB_RXINTERVAL5_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXMAXP6 register. // //***************************************************************************** -#define USB_TXMAXP6_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP6_MAXLOAD_M 0x07FF // Maximum Payload #define USB_TXMAXP6_MAXLOAD_S 0 //***************************************************************************** @@ -1811,37 +1334,37 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXCSRL6 register. // //***************************************************************************** -#define USB_TXCSRL6_NAKTO 0x00000080 // NAK Timeout -#define USB_TXCSRL6_CLRDT 0x00000040 // Clear Data Toggle -#define USB_TXCSRL6_STALLED 0x00000020 // Endpoint Stalled -#define USB_TXCSRL6_STALL 0x00000010 // Send STALL -#define USB_TXCSRL6_SETUP 0x00000010 // Setup Packet -#define USB_TXCSRL6_FLUSH 0x00000008 // Flush FIFO -#define USB_TXCSRL6_ERROR 0x00000004 // Error -#define USB_TXCSRL6_UNDRN 0x00000004 // Underrun -#define USB_TXCSRL6_FIFONE 0x00000002 // FIFO Not Empty -#define USB_TXCSRL6_TXRDY 0x00000001 // Transmit Packet Ready +#define USB_TXCSRL6_NAKTO 0x0080 // NAK Timeout +#define USB_TXCSRL6_CLRDT 0x0040 // Clear Data Toggle +#define USB_TXCSRL6_STALLED 0x0020 // Endpoint Stalled +#define USB_TXCSRL6_STALL 0x0010 // Send STALL +#define USB_TXCSRL6_SETUP 0x0010 // Setup Packet +#define USB_TXCSRL6_FLUSH 0x0008 // Flush FIFO +#define USB_TXCSRL6_ERROR 0x0004 // Error +#define USB_TXCSRL6_UNDRN 0x0004 // Underrun +#define USB_TXCSRL6_FIFONE 0x0002 // FIFO Not Empty +#define USB_TXCSRL6_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRH6 register. // //***************************************************************************** -#define USB_TXCSRH6_AUTOSET 0x00000080 // Auto Set -#define USB_TXCSRH6_ISO 0x00000040 // Isochronous Transfers -#define USB_TXCSRH6_MODE 0x00000020 // Mode -#define USB_TXCSRH6_DMAEN 0x00000010 // DMA Request Enable -#define USB_TXCSRH6_FDT 0x00000008 // Force Data Toggle -#define USB_TXCSRH6_DMAMOD 0x00000004 // DMA Request Mode -#define USB_TXCSRH6_DTWE 0x00000002 // Data Toggle Write Enable -#define USB_TXCSRH6_DT 0x00000001 // Data Toggle +#define USB_TXCSRH6_AUTOSET 0x0080 // Auto Set +#define USB_TXCSRH6_ISO 0x0040 // Isochronous Transfers +#define USB_TXCSRH6_MODE 0x0020 // Mode +#define USB_TXCSRH6_DMAEN 0x0010 // DMA Request Enable +#define USB_TXCSRH6_FDT 0x0008 // Force Data Toggle +#define USB_TXCSRH6_DMAMOD 0x0004 // DMA Request Mode +#define USB_TXCSRH6_DTWE 0x0002 // Data Toggle Write Enable +#define USB_TXCSRH6_DT 0x0001 // Data Toggle //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXMAXP6 register. // //***************************************************************************** -#define USB_RXMAXP6_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP6_MAXLOAD_M 0x07FF // Maximum Payload #define USB_RXMAXP6_MAXLOAD_S 0 //***************************************************************************** @@ -1849,33 +1372,33 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCSRL6 register. // //***************************************************************************** -#define USB_RXCSRL6_CLRDT 0x00000080 // Clear Data Toggle -#define USB_RXCSRL6_STALLED 0x00000040 // Endpoint Stalled -#define USB_RXCSRL6_REQPKT 0x00000020 // Request Packet -#define USB_RXCSRL6_STALL 0x00000020 // Send STALL -#define USB_RXCSRL6_FLUSH 0x00000010 // Flush FIFO -#define USB_RXCSRL6_NAKTO 0x00000008 // NAK Timeout -#define USB_RXCSRL6_DATAERR 0x00000008 // Data Error -#define USB_RXCSRL6_ERROR 0x00000004 // Error -#define USB_RXCSRL6_OVER 0x00000004 // Overrun -#define USB_RXCSRL6_FULL 0x00000002 // FIFO Full -#define USB_RXCSRL6_RXRDY 0x00000001 // Receive Packet Ready +#define USB_RXCSRL6_CLRDT 0x0080 // Clear Data Toggle +#define USB_RXCSRL6_STALLED 0x0040 // Endpoint Stalled +#define USB_RXCSRL6_REQPKT 0x0020 // Request Packet +#define USB_RXCSRL6_STALL 0x0020 // Send STALL +#define USB_RXCSRL6_FLUSH 0x0010 // Flush FIFO +#define USB_RXCSRL6_NAKTO 0x0008 // NAK Timeout +#define USB_RXCSRL6_DATAERR 0x0008 // Data Error +#define USB_RXCSRL6_ERROR 0x0004 // Error +#define USB_RXCSRL6_OVER 0x0004 // Overrun +#define USB_RXCSRL6_FULL 0x0002 // FIFO Full +#define USB_RXCSRL6_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRH6 register. // //***************************************************************************** -#define USB_RXCSRH6_AUTOCL 0x00000080 // Auto Clear -#define USB_RXCSRH6_AUTORQ 0x00000040 // Auto Request -#define USB_RXCSRH6_ISO 0x00000040 // Isochronous Transfers -#define USB_RXCSRH6_DMAEN 0x00000020 // DMA Request Enable -#define USB_RXCSRH6_DISNYET 0x00000010 // Disable NYET -#define USB_RXCSRH6_PIDERR 0x00000010 // PID Error -#define USB_RXCSRH6_DMAMOD 0x00000008 // DMA Request Mode -#define USB_RXCSRH6_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_RXCSRH6_DT 0x00000002 // Data Toggle -#define USB_RXCSRH6_INCOMPRX 0x00000001 // Incomplete RX Transmission +#define USB_RXCSRH6_AUTOCL 0x0080 // Auto Clear +#define USB_RXCSRH6_AUTORQ 0x0040 // Auto Request +#define USB_RXCSRH6_ISO 0x0040 // Isochronous Transfers +#define USB_RXCSRH6_DMAEN 0x0020 // DMA Request Enable +#define USB_RXCSRH6_DISNYET 0x0010 // Disable NYET +#define USB_RXCSRH6_PIDERR 0x0010 // PID Error +#define USB_RXCSRH6_DMAMOD 0x0008 // DMA Request Mode +#define USB_RXCSRH6_DTWE 0x0004 // Data Toggle Write Enable +#define USB_RXCSRH6_DT 0x0002 // Data Toggle +#define USB_RXCSRH6_INCOMPRX 0x0001 // Incomplete RX Transmission // Status //***************************************************************************** @@ -1883,7 +1406,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCOUNT6 register. // //***************************************************************************** -#define USB_RXCOUNT6_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT6_COUNT_M 0x1FFF // Receive Packet Count #define USB_RXCOUNT6_COUNT_S 0 //***************************************************************************** @@ -1891,17 +1414,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXTYPE6 register. // //***************************************************************************** -#define USB_TXTYPE6_SPEED_M 0x000000C0 // Operating Speed -#define USB_TXTYPE6_SPEED_DFLT 0x00000000 // Default -#define USB_TXTYPE6_SPEED_HIGH 0x00000040 // High -#define USB_TXTYPE6_SPEED_FULL 0x00000080 // Full -#define USB_TXTYPE6_SPEED_LOW 0x000000C0 // Low -#define USB_TXTYPE6_PROTO_M 0x00000030 // Protocol -#define USB_TXTYPE6_PROTO_CTRL 0x00000000 // Control -#define USB_TXTYPE6_PROTO_ISOC 0x00000010 // Isochronous -#define USB_TXTYPE6_PROTO_BULK 0x00000020 // Bulk -#define USB_TXTYPE6_PROTO_INT 0x00000030 // Interrupt -#define USB_TXTYPE6_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE6_SPEED_M 0x00C0 // Operating Speed +#define USB_TXTYPE6_SPEED_DFLT 0x0000 // Default +#define USB_TXTYPE6_SPEED_HIGH 0x0040 // High +#define USB_TXTYPE6_SPEED_FULL 0x0080 // Full +#define USB_TXTYPE6_SPEED_LOW 0x00C0 // Low +#define USB_TXTYPE6_PROTO_M 0x0030 // Protocol +#define USB_TXTYPE6_PROTO_CTRL 0x0000 // Control +#define USB_TXTYPE6_PROTO_ISOC 0x0010 // Isochronous +#define USB_TXTYPE6_PROTO_BULK 0x0020 // Bulk +#define USB_TXTYPE6_PROTO_INT 0x0030 // Interrupt +#define USB_TXTYPE6_TEP_M 0x000F // Target Endpoint Number #define USB_TXTYPE6_TEP_S 0 //***************************************************************************** @@ -1910,31 +1433,27 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXINTERVAL6_TXPOLL_M \ - 0x000000FF // TX Polling -#define USB_TXINTERVAL6_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_TXINTERVAL6_TXPOLL_S \ - 0 -#define USB_TXINTERVAL6_NAKLMT_S \ - 0 +#define USB_TXINTERVAL6_TXPOLL_M 0x00FF // TX Polling +#define USB_TXINTERVAL6_NAKLMT_M 0x00FF // NAK Limit +#define USB_TXINTERVAL6_TXPOLL_S 0 +#define USB_TXINTERVAL6_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXTYPE6 register. // //***************************************************************************** -#define USB_RXTYPE6_SPEED_M 0x000000C0 // Operating Speed -#define USB_RXTYPE6_SPEED_DFLT 0x00000000 // Default -#define USB_RXTYPE6_SPEED_HIGH 0x00000040 // High -#define USB_RXTYPE6_SPEED_FULL 0x00000080 // Full -#define USB_RXTYPE6_SPEED_LOW 0x000000C0 // Low -#define USB_RXTYPE6_PROTO_M 0x00000030 // Protocol -#define USB_RXTYPE6_PROTO_CTRL 0x00000000 // Control -#define USB_RXTYPE6_PROTO_ISOC 0x00000010 // Isochronous -#define USB_RXTYPE6_PROTO_BULK 0x00000020 // Bulk -#define USB_RXTYPE6_PROTO_INT 0x00000030 // Interrupt -#define USB_RXTYPE6_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE6_SPEED_M 0x00C0 // Operating Speed +#define USB_RXTYPE6_SPEED_DFLT 0x0000 // Default +#define USB_RXTYPE6_SPEED_HIGH 0x0040 // High +#define USB_RXTYPE6_SPEED_FULL 0x0080 // Full +#define USB_RXTYPE6_SPEED_LOW 0x00C0 // Low +#define USB_RXTYPE6_PROTO_M 0x0030 // Protocol +#define USB_RXTYPE6_PROTO_CTRL 0x0000 // Control +#define USB_RXTYPE6_PROTO_ISOC 0x0010 // Isochronous +#define USB_RXTYPE6_PROTO_BULK 0x0020 // Bulk +#define USB_RXTYPE6_PROTO_INT 0x0030 // Interrupt +#define USB_RXTYPE6_TEP_M 0x000F // Target Endpoint Number #define USB_RXTYPE6_TEP_S 0 //***************************************************************************** @@ -1943,21 +1462,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXINTERVAL6_TXPOLL_M \ - 0x000000FF // RX Polling -#define USB_RXINTERVAL6_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_RXINTERVAL6_NAKLMT_S \ - 0 -#define USB_RXINTERVAL6_TXPOLL_S \ - 0 +#define USB_RXINTERVAL6_TXPOLL_M 0x00FF // RX Polling +#define USB_RXINTERVAL6_NAKLMT_M 0x00FF // NAK Limit +#define USB_RXINTERVAL6_NAKLMT_S 0 +#define USB_RXINTERVAL6_TXPOLL_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXMAXP7 register. // //***************************************************************************** -#define USB_TXMAXP7_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP7_MAXLOAD_M 0x07FF // Maximum Payload #define USB_TXMAXP7_MAXLOAD_S 0 //***************************************************************************** @@ -1965,37 +1480,37 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXCSRL7 register. // //***************************************************************************** -#define USB_TXCSRL7_NAKTO 0x00000080 // NAK Timeout -#define USB_TXCSRL7_CLRDT 0x00000040 // Clear Data Toggle -#define USB_TXCSRL7_STALLED 0x00000020 // Endpoint Stalled -#define USB_TXCSRL7_STALL 0x00000010 // Send STALL -#define USB_TXCSRL7_SETUP 0x00000010 // Setup Packet -#define USB_TXCSRL7_FLUSH 0x00000008 // Flush FIFO -#define USB_TXCSRL7_ERROR 0x00000004 // Error -#define USB_TXCSRL7_UNDRN 0x00000004 // Underrun -#define USB_TXCSRL7_FIFONE 0x00000002 // FIFO Not Empty -#define USB_TXCSRL7_TXRDY 0x00000001 // Transmit Packet Ready +#define USB_TXCSRL7_NAKTO 0x0080 // NAK Timeout +#define USB_TXCSRL7_CLRDT 0x0040 // Clear Data Toggle +#define USB_TXCSRL7_STALLED 0x0020 // Endpoint Stalled +#define USB_TXCSRL7_STALL 0x0010 // Send STALL +#define USB_TXCSRL7_SETUP 0x0010 // Setup Packet +#define USB_TXCSRL7_FLUSH 0x0008 // Flush FIFO +#define USB_TXCSRL7_ERROR 0x0004 // Error +#define USB_TXCSRL7_UNDRN 0x0004 // Underrun +#define USB_TXCSRL7_FIFONE 0x0002 // FIFO Not Empty +#define USB_TXCSRL7_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRH7 register. // //***************************************************************************** -#define USB_TXCSRH7_AUTOSET 0x00000080 // Auto Set -#define USB_TXCSRH7_ISO 0x00000040 // Isochronous Transfers -#define USB_TXCSRH7_MODE 0x00000020 // Mode -#define USB_TXCSRH7_DMAEN 0x00000010 // DMA Request Enable -#define USB_TXCSRH7_FDT 0x00000008 // Force Data Toggle -#define USB_TXCSRH7_DMAMOD 0x00000004 // DMA Request Mode -#define USB_TXCSRH7_DTWE 0x00000002 // Data Toggle Write Enable -#define USB_TXCSRH7_DT 0x00000001 // Data Toggle +#define USB_TXCSRH7_AUTOSET 0x0080 // Auto Set +#define USB_TXCSRH7_ISO 0x0040 // Isochronous Transfers +#define USB_TXCSRH7_MODE 0x0020 // Mode +#define USB_TXCSRH7_DMAEN 0x0010 // DMA Request Enable +#define USB_TXCSRH7_FDT 0x0008 // Force Data Toggle +#define USB_TXCSRH7_DMAMOD 0x0004 // DMA Request Mode +#define USB_TXCSRH7_DTWE 0x0002 // Data Toggle Write Enable +#define USB_TXCSRH7_DT 0x0001 // Data Toggle //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXMAXP7 register. // //***************************************************************************** -#define USB_RXMAXP7_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP7_MAXLOAD_M 0x07FF // Maximum Payload #define USB_RXMAXP7_MAXLOAD_S 0 //***************************************************************************** @@ -2003,33 +1518,33 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCSRL7 register. // //***************************************************************************** -#define USB_RXCSRL7_CLRDT 0x00000080 // Clear Data Toggle -#define USB_RXCSRL7_STALLED 0x00000040 // Endpoint Stalled -#define USB_RXCSRL7_REQPKT 0x00000020 // Request Packet -#define USB_RXCSRL7_STALL 0x00000020 // Send STALL -#define USB_RXCSRL7_FLUSH 0x00000010 // Flush FIFO -#define USB_RXCSRL7_DATAERR 0x00000008 // Data Error -#define USB_RXCSRL7_NAKTO 0x00000008 // NAK Timeout -#define USB_RXCSRL7_ERROR 0x00000004 // Error -#define USB_RXCSRL7_OVER 0x00000004 // Overrun -#define USB_RXCSRL7_FULL 0x00000002 // FIFO Full -#define USB_RXCSRL7_RXRDY 0x00000001 // Receive Packet Ready +#define USB_RXCSRL7_CLRDT 0x0080 // Clear Data Toggle +#define USB_RXCSRL7_STALLED 0x0040 // Endpoint Stalled +#define USB_RXCSRL7_REQPKT 0x0020 // Request Packet +#define USB_RXCSRL7_STALL 0x0020 // Send STALL +#define USB_RXCSRL7_FLUSH 0x0010 // Flush FIFO +#define USB_RXCSRL7_DATAERR 0x0008 // Data Error +#define USB_RXCSRL7_NAKTO 0x0008 // NAK Timeout +#define USB_RXCSRL7_ERROR 0x0004 // Error +#define USB_RXCSRL7_OVER 0x0004 // Overrun +#define USB_RXCSRL7_FULL 0x0002 // FIFO Full +#define USB_RXCSRL7_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRH7 register. // //***************************************************************************** -#define USB_RXCSRH7_AUTOCL 0x00000080 // Auto Clear -#define USB_RXCSRH7_ISO 0x00000040 // Isochronous Transfers -#define USB_RXCSRH7_AUTORQ 0x00000040 // Auto Request -#define USB_RXCSRH7_DMAEN 0x00000020 // DMA Request Enable -#define USB_RXCSRH7_PIDERR 0x00000010 // PID Error -#define USB_RXCSRH7_DISNYET 0x00000010 // Disable NYET -#define USB_RXCSRH7_DMAMOD 0x00000008 // DMA Request Mode -#define USB_RXCSRH7_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_RXCSRH7_DT 0x00000002 // Data Toggle -#define USB_RXCSRH7_INCOMPRX 0x00000001 // Incomplete RX Transmission +#define USB_RXCSRH7_AUTOCL 0x0080 // Auto Clear +#define USB_RXCSRH7_ISO 0x0040 // Isochronous Transfers +#define USB_RXCSRH7_AUTORQ 0x0040 // Auto Request +#define USB_RXCSRH7_DMAEN 0x0020 // DMA Request Enable +#define USB_RXCSRH7_PIDERR 0x0010 // PID Error +#define USB_RXCSRH7_DISNYET 0x0010 // Disable NYET +#define USB_RXCSRH7_DMAMOD 0x0008 // DMA Request Mode +#define USB_RXCSRH7_DTWE 0x0004 // Data Toggle Write Enable +#define USB_RXCSRH7_DT 0x0002 // Data Toggle +#define USB_RXCSRH7_INCOMPRX 0x0001 // Incomplete RX Transmission // Status //***************************************************************************** @@ -2037,7 +1552,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCOUNT7 register. // //***************************************************************************** -#define USB_RXCOUNT7_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT7_COUNT_M 0x1FFF // Receive Packet Count #define USB_RXCOUNT7_COUNT_S 0 //***************************************************************************** @@ -2045,17 +1560,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXTYPE7 register. // //***************************************************************************** -#define USB_TXTYPE7_SPEED_M 0x000000C0 // Operating Speed -#define USB_TXTYPE7_SPEED_DFLT 0x00000000 // Default -#define USB_TXTYPE7_SPEED_HIGH 0x00000040 // High -#define USB_TXTYPE7_SPEED_FULL 0x00000080 // Full -#define USB_TXTYPE7_SPEED_LOW 0x000000C0 // Low -#define USB_TXTYPE7_PROTO_M 0x00000030 // Protocol -#define USB_TXTYPE7_PROTO_CTRL 0x00000000 // Control -#define USB_TXTYPE7_PROTO_ISOC 0x00000010 // Isochronous -#define USB_TXTYPE7_PROTO_BULK 0x00000020 // Bulk -#define USB_TXTYPE7_PROTO_INT 0x00000030 // Interrupt -#define USB_TXTYPE7_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE7_SPEED_M 0x00C0 // Operating Speed +#define USB_TXTYPE7_SPEED_DFLT 0x0000 // Default +#define USB_TXTYPE7_SPEED_HIGH 0x0040 // High +#define USB_TXTYPE7_SPEED_FULL 0x0080 // Full +#define USB_TXTYPE7_SPEED_LOW 0x00C0 // Low +#define USB_TXTYPE7_PROTO_M 0x0030 // Protocol +#define USB_TXTYPE7_PROTO_CTRL 0x0000 // Control +#define USB_TXTYPE7_PROTO_ISOC 0x0010 // Isochronous +#define USB_TXTYPE7_PROTO_BULK 0x0020 // Bulk +#define USB_TXTYPE7_PROTO_INT 0x0030 // Interrupt +#define USB_TXTYPE7_TEP_M 0x000F // Target Endpoint Number #define USB_TXTYPE7_TEP_S 0 //***************************************************************************** @@ -2064,31 +1579,27 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXINTERVAL7_TXPOLL_M \ - 0x000000FF // TX Polling -#define USB_TXINTERVAL7_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_TXINTERVAL7_NAKLMT_S \ - 0 -#define USB_TXINTERVAL7_TXPOLL_S \ - 0 +#define USB_TXINTERVAL7_TXPOLL_M 0x00FF // TX Polling +#define USB_TXINTERVAL7_NAKLMT_M 0x00FF // NAK Limit +#define USB_TXINTERVAL7_NAKLMT_S 0 +#define USB_TXINTERVAL7_TXPOLL_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXTYPE7 register. // //***************************************************************************** -#define USB_RXTYPE7_SPEED_M 0x000000C0 // Operating Speed -#define USB_RXTYPE7_SPEED_DFLT 0x00000000 // Default -#define USB_RXTYPE7_SPEED_HIGH 0x00000040 // High -#define USB_RXTYPE7_SPEED_FULL 0x00000080 // Full -#define USB_RXTYPE7_SPEED_LOW 0x000000C0 // Low -#define USB_RXTYPE7_PROTO_M 0x00000030 // Protocol -#define USB_RXTYPE7_PROTO_CTRL 0x00000000 // Control -#define USB_RXTYPE7_PROTO_ISOC 0x00000010 // Isochronous -#define USB_RXTYPE7_PROTO_BULK 0x00000020 // Bulk -#define USB_RXTYPE7_PROTO_INT 0x00000030 // Interrupt -#define USB_RXTYPE7_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE7_SPEED_M 0x00C0 // Operating Speed +#define USB_RXTYPE7_SPEED_DFLT 0x0000 // Default +#define USB_RXTYPE7_SPEED_HIGH 0x0040 // High +#define USB_RXTYPE7_SPEED_FULL 0x0080 // Full +#define USB_RXTYPE7_SPEED_LOW 0x00C0 // Low +#define USB_RXTYPE7_PROTO_M 0x0030 // Protocol +#define USB_RXTYPE7_PROTO_CTRL 0x0000 // Control +#define USB_RXTYPE7_PROTO_ISOC 0x0010 // Isochronous +#define USB_RXTYPE7_PROTO_BULK 0x0020 // Bulk +#define USB_RXTYPE7_PROTO_INT 0x0030 // Interrupt +#define USB_RXTYPE7_TEP_M 0x000F // Target Endpoint Number #define USB_RXTYPE7_TEP_S 0 //***************************************************************************** @@ -2097,47 +1608,43 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXINTERVAL7_TXPOLL_M \ - 0x000000FF // RX Polling -#define USB_RXINTERVAL7_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_RXINTERVAL7_NAKLMT_S \ - 0 -#define USB_RXINTERVAL7_TXPOLL_S \ - 0 +#define USB_RXINTERVAL7_TXPOLL_M 0x00FF // RX Polling +#define USB_RXINTERVAL7_NAKLMT_M 0x00FF // NAK Limit +#define USB_RXINTERVAL7_NAKLMT_S 0 +#define USB_RXINTERVAL7_TXPOLL_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_DMAINTR register. // //***************************************************************************** -#define USB_DMAINTR_CH7 0x00000080 // Channel 7 DMA Interrupt -#define USB_DMAINTR_CH6 0x00000040 // Channel 6 DMA Interrupt -#define USB_DMAINTR_CH5 0x00000020 // Channel 5 DMA Interrupt -#define USB_DMAINTR_CH4 0x00000010 // Channel 4 DMA Interrupt -#define USB_DMAINTR_CH3 0x00000008 // Channel 3 DMA Interrupt -#define USB_DMAINTR_CH2 0x00000004 // Channel 2 DMA Interrupt -#define USB_DMAINTR_CH1 0x00000002 // Channel 1 DMA Interrupt -#define USB_DMAINTR_CH0 0x00000001 // Channel 0 DMA Interrupt +#define USB_DMAINTR_CH7 0x0080 // Channel 7 DMA Interrupt +#define USB_DMAINTR_CH6 0x0040 // Channel 6 DMA Interrupt +#define USB_DMAINTR_CH5 0x0020 // Channel 5 DMA Interrupt +#define USB_DMAINTR_CH4 0x0010 // Channel 4 DMA Interrupt +#define USB_DMAINTR_CH3 0x0008 // Channel 3 DMA Interrupt +#define USB_DMAINTR_CH2 0x0004 // Channel 2 DMA Interrupt +#define USB_DMAINTR_CH1 0x0002 // Channel 1 DMA Interrupt +#define USB_DMAINTR_CH0 0x0001 // Channel 0 DMA Interrupt //***************************************************************************** // // The following are defines for the bit fields in the USB_O_DMACTL0 register. // //***************************************************************************** -#define USB_DMACTL0_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL0_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL0_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL0_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL0_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL0_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL0_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL0_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL0_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL0_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL0_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL0_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL0_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL0_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL0_DIR 0x00000002 // DMA Direction -#define USB_DMACTL0_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL0_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL0_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL0_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL0_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL0_DIR 0x0002 // DMA Direction +#define USB_DMACTL0_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL0_EP_S 4 //***************************************************************************** @@ -2162,19 +1669,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DMACTL1 register. // //***************************************************************************** -#define USB_DMACTL1_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL1_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL1_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL1_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL1_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL1_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL1_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL1_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL1_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL1_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL1_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL1_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL1_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL1_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL1_DIR 0x00000002 // DMA Direction -#define USB_DMACTL1_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL1_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL1_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL1_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL1_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL1_DIR 0x0002 // DMA Direction +#define USB_DMACTL1_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL1_EP_S 4 //***************************************************************************** @@ -2199,19 +1706,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DMACTL2 register. // //***************************************************************************** -#define USB_DMACTL2_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL2_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL2_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL2_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL2_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL2_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL2_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL2_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL2_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL2_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL2_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL2_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL2_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL2_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL2_DIR 0x00000002 // DMA Direction -#define USB_DMACTL2_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL2_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL2_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL2_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL2_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL2_DIR 0x0002 // DMA Direction +#define USB_DMACTL2_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL2_EP_S 4 //***************************************************************************** @@ -2236,19 +1743,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DMACTL3 register. // //***************************************************************************** -#define USB_DMACTL3_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL3_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL3_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL3_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL3_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL3_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL3_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL3_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL3_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL3_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL3_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL3_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL3_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL3_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL3_DIR 0x00000002 // DMA Direction -#define USB_DMACTL3_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL3_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL3_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL3_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL3_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL3_DIR 0x0002 // DMA Direction +#define USB_DMACTL3_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL3_EP_S 4 //***************************************************************************** @@ -2273,19 +1780,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DMACTL4 register. // //***************************************************************************** -#define USB_DMACTL4_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL4_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL4_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL4_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL4_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL4_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL4_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL4_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL4_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL4_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL4_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL4_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL4_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL4_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL4_DIR 0x00000002 // DMA Direction -#define USB_DMACTL4_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL4_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL4_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL4_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL4_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL4_DIR 0x0002 // DMA Direction +#define USB_DMACTL4_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL4_EP_S 4 //***************************************************************************** @@ -2310,19 +1817,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DMACTL5 register. // //***************************************************************************** -#define USB_DMACTL5_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL5_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL5_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL5_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL5_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL5_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL5_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL5_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL5_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL5_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL5_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL5_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL5_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL5_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL5_DIR 0x00000002 // DMA Direction -#define USB_DMACTL5_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL5_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL5_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL5_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL5_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL5_DIR 0x0002 // DMA Direction +#define USB_DMACTL5_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL5_EP_S 4 //***************************************************************************** @@ -2347,19 +1854,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DMACTL6 register. // //***************************************************************************** -#define USB_DMACTL6_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL6_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL6_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL6_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL6_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL6_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL6_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL6_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL6_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL6_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL6_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL6_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL6_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL6_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL6_DIR 0x00000002 // DMA Direction -#define USB_DMACTL6_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL6_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL6_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL6_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL6_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL6_DIR 0x0002 // DMA Direction +#define USB_DMACTL6_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL6_EP_S 4 //***************************************************************************** @@ -2384,19 +1891,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DMACTL7 register. // //***************************************************************************** -#define USB_DMACTL7_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL7_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL7_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL7_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL7_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL7_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL7_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL7_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL7_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL7_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL7_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL7_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL7_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL7_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL7_DIR 0x00000002 // DMA Direction -#define USB_DMACTL7_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL7_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL7_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL7_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL7_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL7_DIR 0x0002 // DMA Direction +#define USB_DMACTL7_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL7_EP_S 4 //***************************************************************************** @@ -2422,7 +1929,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RQPKTCOUNT1_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT1_M 0xFFFF // Block Transfer Packet Count #define USB_RQPKTCOUNT1_S 0 //***************************************************************************** @@ -2431,7 +1938,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RQPKTCOUNT2_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT2_M 0xFFFF // Block Transfer Packet Count #define USB_RQPKTCOUNT2_S 0 //***************************************************************************** @@ -2440,7 +1947,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RQPKTCOUNT3_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT3_M 0xFFFF // Block Transfer Packet Count #define USB_RQPKTCOUNT3_S 0 //***************************************************************************** @@ -2449,7 +1956,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RQPKTCOUNT4_COUNT_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT4_COUNT_M 0xFFFF // Block Transfer Packet Count #define USB_RQPKTCOUNT4_COUNT_S 0 //***************************************************************************** @@ -2458,7 +1965,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RQPKTCOUNT5_COUNT_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT5_COUNT_M 0xFFFF // Block Transfer Packet Count #define USB_RQPKTCOUNT5_COUNT_S 0 //***************************************************************************** @@ -2467,7 +1974,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RQPKTCOUNT6_COUNT_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT6_COUNT_M 0xFFFF // Block Transfer Packet Count #define USB_RQPKTCOUNT6_COUNT_S 0 //***************************************************************************** @@ -2476,7 +1983,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RQPKTCOUNT7_COUNT_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT7_COUNT_M 0xFFFF // Block Transfer Packet Count #define USB_RQPKTCOUNT7_COUNT_S 0 //***************************************************************************** @@ -2485,19 +1992,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXDPKTBUFDIS_EP7 0x00000080 // EP7 RX Double-Packet Buffer +#define USB_RXDPKTBUFDIS_EP7 0x0080 // EP7 RX Double-Packet Buffer // Disable -#define USB_RXDPKTBUFDIS_EP6 0x00000040 // EP6 RX Double-Packet Buffer +#define USB_RXDPKTBUFDIS_EP6 0x0040 // EP6 RX Double-Packet Buffer // Disable -#define USB_RXDPKTBUFDIS_EP5 0x00000020 // EP5 RX Double-Packet Buffer +#define USB_RXDPKTBUFDIS_EP5 0x0020 // EP5 RX Double-Packet Buffer // Disable -#define USB_RXDPKTBUFDIS_EP4 0x00000010 // EP4 RX Double-Packet Buffer +#define USB_RXDPKTBUFDIS_EP4 0x0010 // EP4 RX Double-Packet Buffer // Disable -#define USB_RXDPKTBUFDIS_EP3 0x00000008 // EP3 RX Double-Packet Buffer +#define USB_RXDPKTBUFDIS_EP3 0x0008 // EP3 RX Double-Packet Buffer // Disable -#define USB_RXDPKTBUFDIS_EP2 0x00000004 // EP2 RX Double-Packet Buffer +#define USB_RXDPKTBUFDIS_EP2 0x0004 // EP2 RX Double-Packet Buffer // Disable -#define USB_RXDPKTBUFDIS_EP1 0x00000002 // EP1 RX Double-Packet Buffer +#define USB_RXDPKTBUFDIS_EP1 0x0002 // EP1 RX Double-Packet Buffer // Disable //***************************************************************************** @@ -2506,19 +2013,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXDPKTBUFDIS_EP7 0x00000080 // EP7 TX Double-Packet Buffer +#define USB_TXDPKTBUFDIS_EP7 0x0080 // EP7 TX Double-Packet Buffer // Disable -#define USB_TXDPKTBUFDIS_EP6 0x00000040 // EP6 TX Double-Packet Buffer +#define USB_TXDPKTBUFDIS_EP6 0x0040 // EP6 TX Double-Packet Buffer // Disable -#define USB_TXDPKTBUFDIS_EP5 0x00000020 // EP5 TX Double-Packet Buffer +#define USB_TXDPKTBUFDIS_EP5 0x0020 // EP5 TX Double-Packet Buffer // Disable -#define USB_TXDPKTBUFDIS_EP4 0x00000010 // EP4 TX Double-Packet Buffer +#define USB_TXDPKTBUFDIS_EP4 0x0010 // EP4 TX Double-Packet Buffer // Disable -#define USB_TXDPKTBUFDIS_EP3 0x00000008 // EP3 TX Double-Packet Buffer +#define USB_TXDPKTBUFDIS_EP3 0x0008 // EP3 TX Double-Packet Buffer // Disable -#define USB_TXDPKTBUFDIS_EP2 0x00000004 // EP2 TX Double-Packet Buffer +#define USB_TXDPKTBUFDIS_EP2 0x0004 // EP2 TX Double-Packet Buffer // Disable -#define USB_TXDPKTBUFDIS_EP1 0x00000002 // EP1 TX Double-Packet Buffer +#define USB_TXDPKTBUFDIS_EP1 0x0002 // EP1 TX Double-Packet Buffer // Disable //***************************************************************************** @@ -2526,7 +2033,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_CTO register. // //***************************************************************************** -#define USB_CTO_CCTV_M 0x0000FFFF // Configurable Chirp Timeout Value +#define USB_CTO_CCTV_M 0xFFFF // Configurable Chirp Timeout Value #define USB_CTO_CCTV_S 0 //***************************************************************************** @@ -2534,7 +2041,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_HHSRTN register. // //***************************************************************************** -#define USB_HHSRTN_HHSRTN_M 0x0000FFFF // HIgh Speed to UTM Operating +#define USB_HHSRTN_HHSRTN_M 0xFFFF // HIgh Speed to UTM Operating // Delay #define USB_HHSRTN_HHSRTN_S 0 @@ -2543,7 +2050,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_HSBT register. // //***************************************************************************** -#define USB_HSBT_HSBT_M 0x0000000F // High Speed Timeout Adder +#define USB_HSBT_HSBT_M 0x000F // High Speed Timeout Adder #define USB_HSBT_HSBT_S 0 //***************************************************************************** @@ -2551,11 +2058,11 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_LPMATTR register. // //***************************************************************************** -#define USB_LPMATTR_ENDPT_M 0x0000F000 // Endpoint -#define USB_LPMATTR_RMTWAK 0x00000100 // Remote Wake -#define USB_LPMATTR_HIRD_M 0x000000F0 // Host Initiated Resume Duration -#define USB_LPMATTR_LS_M 0x0000000F // Link State -#define USB_LPMATTR_LS_L1 0x00000001 // Sleep State (L1) +#define USB_LPMATTR_ENDPT_M 0xF000 // Endpoint +#define USB_LPMATTR_RMTWAK 0x0100 // Remote Wake +#define USB_LPMATTR_HIRD_M 0x00F0 // Host Initiated Resume Duration +#define USB_LPMATTR_LS_M 0x000F // Link State +#define USB_LPMATTR_LS_L1 0x0001 // Sleep State (L1) #define USB_LPMATTR_ENDPT_S 12 #define USB_LPMATTR_HIRD_S 4 @@ -2564,56 +2071,56 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_LPMCNTRL register. // //***************************************************************************** -#define USB_LPMCNTRL_NAK 0x00000010 // LPM NAK -#define USB_LPMCNTRL_EN_M 0x0000000C // LPM Enable -#define USB_LPMCNTRL_EN_NONE 0x00000000 // LPM and Extended transactions +#define USB_LPMCNTRL_NAK 0x0010 // LPM NAK +#define USB_LPMCNTRL_EN_M 0x000C // LPM Enable +#define USB_LPMCNTRL_EN_NONE 0x0000 // LPM and Extended transactions // are not supported. In this case, // the USB does not respond to LPM // transactions and LPM // transactions cause a timeout -#define USB_LPMCNTRL_EN_EXT 0x00000004 // LPM is not supported but +#define USB_LPMCNTRL_EN_EXT 0x0004 // LPM is not supported but // extended transactions are // supported. In this case, the USB // does respond to an LPM // transaction with a STALL -#define USB_LPMCNTRL_EN_LPMEXT 0x0000000C // The USB supports LPM extended +#define USB_LPMCNTRL_EN_LPMEXT 0x000C // The USB supports LPM extended // transactions. In this case, the // USB responds with a NYET or an // ACK as determined by the value // of TXLPM and other conditions -#define USB_LPMCNTRL_RES 0x00000002 // LPM Resume -#define USB_LPMCNTRL_TXLPM 0x00000001 // Transmit LPM Transaction Enable +#define USB_LPMCNTRL_RES 0x0002 // LPM Resume +#define USB_LPMCNTRL_TXLPM 0x0001 // Transmit LPM Transaction Enable //***************************************************************************** // // The following are defines for the bit fields in the USB_O_LPMIM register. // //***************************************************************************** -#define USB_LPMIM_ERR 0x00000020 // LPM Error Interrupt Mask -#define USB_LPMIM_RES 0x00000010 // LPM Resume Interrupt Mask -#define USB_LPMIM_NC 0x00000008 // LPM NC Interrupt Mask -#define USB_LPMIM_ACK 0x00000004 // LPM ACK Interrupt Mask -#define USB_LPMIM_NY 0x00000002 // LPM NY Interrupt Mask -#define USB_LPMIM_STALL 0x00000001 // LPM STALL Interrupt Mask +#define USB_LPMIM_ERR 0x0020 // LPM Error Interrupt Mask +#define USB_LPMIM_RES 0x0010 // LPM Resume Interrupt Mask +#define USB_LPMIM_NC 0x0008 // LPM NC Interrupt Mask +#define USB_LPMIM_ACK 0x0004 // LPM ACK Interrupt Mask +#define USB_LPMIM_NY 0x0002 // LPM NY Interrupt Mask +#define USB_LPMIM_STALL 0x0001 // LPM STALL Interrupt Mask //***************************************************************************** // // The following are defines for the bit fields in the USB_O_LPMRIS register. // //***************************************************************************** -#define USB_LPMRIS_ERR 0x00000020 // LPM Interrupt Status -#define USB_LPMRIS_RES 0x00000010 // LPM Resume Interrupt Status -#define USB_LPMRIS_NC 0x00000008 // LPM NC Interrupt Status -#define USB_LPMRIS_ACK 0x00000004 // LPM ACK Interrupt Status -#define USB_LPMRIS_NY 0x00000002 // LPM NY Interrupt Status -#define USB_LPMRIS_LPMST 0x00000001 // LPM STALL Interrupt Status +#define USB_LPMRIS_ERR 0x0020 // LPM Interrupt Status +#define USB_LPMRIS_RES 0x0010 // LPM Resume Interrupt Status +#define USB_LPMRIS_NC 0x0008 // LPM NC Interrupt Status +#define USB_LPMRIS_ACK 0x0004 // LPM ACK Interrupt Status +#define USB_LPMRIS_NY 0x0002 // LPM NY Interrupt Status +#define USB_LPMRIS_LPMST 0x0001 // LPM STALL Interrupt Status //***************************************************************************** // // The following are defines for the bit fields in the USB_O_LPMFADDR register. // //***************************************************************************** -#define USB_LPMFADDR_ADDR_M 0x0000007F // LPM Function Address +#define USB_LPMFADDR_ADDR_M 0x007F // LPM Function Address #define USB_LPMFADDR_ADDR_S 0 //***************************************************************************** @@ -2621,22 +2128,22 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_EPC register. // //***************************************************************************** -#define USB_EPC_PFLTACT_M 0x00000300 // Power Fault Action -#define USB_EPC_PFLTACT_UNCHG 0x00000000 // Unchanged -#define USB_EPC_PFLTACT_TRIS 0x00000100 // Tristate -#define USB_EPC_PFLTACT_LOW 0x00000200 // Low -#define USB_EPC_PFLTACT_HIGH 0x00000300 // High -#define USB_EPC_PFLTAEN 0x00000040 // Power Fault Action Enable -#define USB_EPC_PFLTSEN_HIGH 0x00000020 // Power Fault Sense -#define USB_EPC_PFLTEN 0x00000010 // Power Fault Input Enable -#define USB_EPC_EPENDE 0x00000004 // EPEN Drive Enable -#define USB_EPC_EPEN_M 0x00000003 // External Power Supply Enable +#define USB_EPC_PFLTACT_M 0x0300 // Power Fault Action +#define USB_EPC_PFLTACT_UNCHG 0x0000 // Unchanged +#define USB_EPC_PFLTACT_TRIS 0x0100 // Tristate +#define USB_EPC_PFLTACT_LOW 0x0200 // Low +#define USB_EPC_PFLTACT_HIGH 0x0300 // High +#define USB_EPC_PFLTAEN 0x0040 // Power Fault Action Enable +#define USB_EPC_PFLTSEN_HIGH 0x0020 // Power Fault Sense +#define USB_EPC_PFLTEN 0x0010 // Power Fault Input Enable +#define USB_EPC_EPENDE 0x0004 // EPEN Drive Enable +#define USB_EPC_EPEN_M 0x0003 // External Power Supply Enable // Configuration -#define USB_EPC_EPEN_LOW 0x00000000 // Power Enable Active Low -#define USB_EPC_EPEN_HIGH 0x00000001 // Power Enable Active High -#define USB_EPC_EPEN_VBLOW 0x00000002 // Power Enable High if VBUS Low +#define USB_EPC_EPEN_LOW 0x0000 // Power Enable Active Low +#define USB_EPC_EPEN_HIGH 0x0001 // Power Enable Active High +#define USB_EPC_EPEN_VBLOW 0x0002 // Power Enable High if VBUS Low // (OTG only) -#define USB_EPC_EPEN_VBHIGH 0x00000003 // Power Enable High if VBUS High +#define USB_EPC_EPEN_VBHIGH 0x0003 // Power Enable High if VBUS High // (OTG only) //***************************************************************************** @@ -2644,21 +2151,21 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_EPCRIS register. // //***************************************************************************** -#define USB_EPCRIS_PF 0x00000001 // USB Power Fault Interrupt Status +#define USB_EPCRIS_PF 0x0001 // USB Power Fault Interrupt Status //***************************************************************************** // // The following are defines for the bit fields in the USB_O_EPCIM register. // //***************************************************************************** -#define USB_EPCIM_PF 0x00000001 // USB Power Fault Interrupt Mask +#define USB_EPCIM_PF 0x0001 // USB Power Fault Interrupt Mask //***************************************************************************** // // The following are defines for the bit fields in the USB_O_EPCISC register. // //***************************************************************************** -#define USB_EPCISC_PF 0x00000001 // USB Power Fault Interrupt Status +#define USB_EPCISC_PF 0x0001 // USB Power Fault Interrupt Status // and Clear //***************************************************************************** @@ -2666,21 +2173,21 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DRRIS register. // //***************************************************************************** -#define USB_DRRIS_RESUME 0x00000001 // RESUME Interrupt Status +#define USB_DRRIS_RESUME 0x0001 // RESUME Interrupt Status //***************************************************************************** // // The following are defines for the bit fields in the USB_O_DRIM register. // //***************************************************************************** -#define USB_DRIM_RESUME 0x00000001 // RESUME Interrupt Mask +#define USB_DRIM_RESUME 0x0001 // RESUME Interrupt Mask //***************************************************************************** // // The following are defines for the bit fields in the USB_O_DRISC register. // //***************************************************************************** -#define USB_DRISC_RESUME 0x00000001 // RESUME Interrupt Status and +#define USB_DRISC_RESUME 0x0001 // RESUME Interrupt Status and // Clear //***************************************************************************** @@ -2688,14 +2195,14 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_GPCS register. // //***************************************************************************** -#define USB_GPCS_DEVMOD_M 0x00000007 // Device Mode -#define USB_GPCS_DEVMOD_OTG 0x00000000 // Use USB0VBUS and USB0ID pin -#define USB_GPCS_DEVMOD_HOST 0x00000002 // Force USB0VBUS and USB0ID low -#define USB_GPCS_DEVMOD_DEV 0x00000003 // Force USB0VBUS and USB0ID high +#define USB_GPCS_DEVMOD_M 0x0007 // Device Mode +#define USB_GPCS_DEVMOD_OTG 0x0000 // Use USB0VBUS and USB0ID pin +#define USB_GPCS_DEVMOD_HOST 0x0002 // Force USB0VBUS and USB0ID low +#define USB_GPCS_DEVMOD_DEV 0x0003 // Force USB0VBUS and USB0ID high #define USB_GPCS_DEVMOD_HOSTVBUS \ - 0x00000004 // Use USB0VBUS and force USB0ID + 0x0004 // Use USB0VBUS and force USB0ID // low -#define USB_GPCS_DEVMOD_DEVVBUS 0x00000005 // Use USB0VBUS and force USB0ID +#define USB_GPCS_DEVMOD_DEVVBUS 0x0005 // Use USB0VBUS and force USB0ID // high //***************************************************************************** @@ -2703,28 +2210,28 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_VDC register. // //***************************************************************************** -#define USB_VDC_VBDEN 0x00000001 // VBUS Droop Enable +#define USB_VDC_VBDEN 0x0001 // VBUS Droop Enable //***************************************************************************** // // The following are defines for the bit fields in the USB_O_VDCRIS register. // //***************************************************************************** -#define USB_VDCRIS_VD 0x00000001 // VBUS Droop Raw Interrupt Status +#define USB_VDCRIS_VD 0x0001 // VBUS Droop Raw Interrupt Status //***************************************************************************** // // The following are defines for the bit fields in the USB_O_VDCIM register. // //***************************************************************************** -#define USB_VDCIM_VD 0x00000001 // VBUS Droop Interrupt Mask +#define USB_VDCIM_VD 0x0001 // VBUS Droop Interrupt Mask //***************************************************************************** // // The following are defines for the bit fields in the USB_O_VDCISC register. // //***************************************************************************** -#define USB_VDCISC_VD 0x00000001 // VBUS Droop Interrupt Status and +#define USB_VDCISC_VD 0x0001 // VBUS Droop Interrupt Status and // Clear //***************************************************************************** @@ -2732,17 +2239,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_PP register. // //***************************************************************************** -#define USB_PP_ECNT_M 0x0000FF00 // Endpoint Count -#define USB_PP_USB_M 0x000000C0 // USB Capability -#define USB_PP_USB_DEVICE 0x00000040 // DEVICE -#define USB_PP_USB_HOSTDEVICE 0x00000080 // HOST -#define USB_PP_USB_OTG 0x000000C0 // OTG -#define USB_PP_ULPI 0x00000020 // ULPI Present -#define USB_PP_PHY 0x00000010 // PHY Present -#define USB_PP_TYPE_M 0x0000000F // Controller Type -#define USB_PP_TYPE_0 0x00000000 // The first-generation USB +#define USB_PP_ECNT_M 0xFF00 // Endpoint Count +#define USB_PP_USB_M 0x00C0 // USB Capability +#define USB_PP_USB_DEVICE 0x0040 // DEVICE +#define USB_PP_USB_HOSTDEVICE 0x0080 // HOST +#define USB_PP_USB_OTG 0x00C0 // OTG +#define USB_PP_ULPI 0x0020 // ULPI Present +#define USB_PP_PHY 0x0010 // PHY Present +#define USB_PP_TYPE_M 0x000F // Controller Type +#define USB_PP_TYPE_0 0x0000 // The first-generation USB // controller -#define USB_PP_TYPE_1 0x00000001 // The second-generation USB +#define USB_PP_TYPE_1 0x0001 // The second-generation USB // controller revision #define USB_PP_ECNT_S 8 @@ -2758,9 +2265,9 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_CC register. // //***************************************************************************** -#define USB_CC_CLKEN 0x00000200 // USB Clock Enable -#define USB_CC_CSD 0x00000100 // Clock Source/Direction -#define USB_CC_CLKDIV_M 0x0000000F // PLL Clock Divisor +#define USB_CC_CLKEN 0x0200 // USB Clock Enable +#define USB_CC_CSD 0x0100 // Clock Source/Direction +#define USB_CC_CLKDIV_M 0x000F // PLL Clock Divisor #define USB_CC_CLKDIV_S 0 #ifdef __cplusplus -- cgit v1.3.1 From e9109f36ba873062812b37f2c40fc88bbf48af67 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 17 Aug 2024 16:34:24 +0700 Subject: refactor fifo configure/setup for dynamic and static fifo --- src/portable/mentor/musb/dcd_musb.c | 86 +++++++++++++++++++++++++++++++---- src/portable/mentor/musb/musb_max32.h | 39 ++++++++-------- src/portable/mentor/musb/musb_ti.h | 3 ++ src/portable/mentor/musb/musb_type.h | 3 +- 4 files changed, 101 insertions(+), 30 deletions(-) diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 36690c952..e9d907828 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -41,7 +41,6 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); // Following symbols must be defined by port header // - musb_dcd_int_enable/disable/clear/get_enable // - musb_dcd_int_handler_enter/exit -// - musb_dcd_setup_fifo: Configuration of the EP's FIFO #if defined(TUP_USBIP_MUSB_TI) #include "musb_ti.h" #elif defined(TUP_USBIP_MUSB_ADI) @@ -88,19 +87,78 @@ typedef struct *------------------------------------------------------------------*/ static dcd_data_t _dcd; +#if MUSB_CFG_DYNAMIC_FIFO + +// musb is configured to use dynamic FIFO sizing. +// FF Size is encodded: 1 << (fifo_size[3:0] + 3) = 8 << fifo_size[3:0] +// FF Address is 8*ff_addr[12:0] +// First 64 bytes are reserved for EP0 +static uint32_t alloced_fifo_bytes; + TU_ATTR_ALWAYS_INLINE static inline void fifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { - musb->index = epnum; const uint8_t is_rx = 1 - dir_in; - -#if MUSB_CFG_DYNAMIC_FIFO + musb->index = epnum; musb->fifo_size[is_rx] = 0; musb->fifo_addr[is_rx] = 0; -#elif defined(TUP_USBIP_MUSB_ADI) +} + +TU_ATTR_ALWAYS_INLINE static inline bool fifo_configure(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps) { + // ffsize is log2(mps) - 3 (round up) + uint8_t ffsize = 28 - tu_min8(28, __builtin_clz(mps)); + // round up to the next power of 2 + if ((8u << ffsize) < mps) { + ++ffsize; + mps = 8 << ffsize; + } + + TU_ASSERT(alloced_fifo_bytes + mps <= MUSB_CFG_DYNAMIC_FIFO_SIZE); + const uint8_t is_rx = 1 - dir_in; + musb->index = epnum; + musb->fifo_addr[is_rx] = alloced_fifo_bytes / 8; + musb->fifo_size[is_rx] = ffsize; + + alloced_fifo_bytes += mps; + + return true; +} + +#else +TU_ATTR_ALWAYS_INLINE static inline void fifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { + const uint8_t is_rx = 1 - dir_in; + musb->index = epnum; + + #if defined(TUP_USBIP_MUSB_ADI) // Analog have custom double buffered in csrh register, disable it musb->indexed_csr.maxp_csr[is_rx].csrh |= MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); + #else + // disable double bufeffered in extended register + #endif +} + +TU_ATTR_ALWAYS_INLINE static inline bool fifo_configure(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps) { + (void) mps; + const uint8_t is_rx = 1 - dir_in; + musb->index = epnum; + + uint8_t csrh = 0; + +#if defined(TUP_USBIP_MUSB_ADI) + csrh = MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); #endif + +#if MUSB_CFG_SHARED_FIFO + if (dir_in) { + csrh |= MUSB_CSRH_TX_MODE; + } +#endif + + musb->indexed_csr.maxp_csr[is_rx].csrh |= csrh; + + return true; } +#endif + static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; @@ -463,6 +521,11 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) // faddr = 0, index = 0, flushes all ep fifos, clears all ep csr, enabled all ep interrupts static void process_bus_reset(uint8_t rhport) { musb_regs_t* musb = MUSB_REGS(rhport); + +#if MUSB_CFG_DYNAMIC_FIFO + alloced_fifo_bytes = CFG_TUD_ENDPOINT0_SIZE; +#endif + /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), a control transfer state is SETUP or STATUS stage. */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.status_out = 0; @@ -594,8 +657,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) pipe->length = 0; pipe->remaining = 0; - musb_regs_t* musb_regs = MUSB_REGS(rhport); - musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); + musb_regs_t* musb = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); const uint8_t is_rx = 1 - dir_in; ep_csr->maxp_csr[is_rx].maxp = mps; @@ -606,10 +669,10 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) csrl |= MUSB_CSRL_FLUSH_FIFO(is_rx); } ep_csr->maxp_csr[is_rx].csrl = csrl; - musb_regs->intren_ep[is_rx] |= TU_BIT(epn); + musb->intren_ep[is_rx] |= TU_BIT(epn); /* Setup FIFO */ - musb_dcd_setup_fifo(rhport, epn, dir_in, mps); + fifo_configure(musb, epn, dir_in, mps); return true; } @@ -619,6 +682,7 @@ void dcd_edpt_close_all(uint8_t rhport) musb_regs_t* musb = MUSB_REGS(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); + musb->intr_txen = 1; /* Enable only EP0 */ musb->intr_rxen = 0; for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { @@ -640,13 +704,15 @@ void dcd_edpt_close_all(uint8_t rhport) fifo_reset(musb, i, 0); fifo_reset(musb, i, 1); - } + alloced_fifo_bytes = CFG_TUD_ENDPOINT0_SIZE; + if (ie) musb_dcd_int_enable(rhport); } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + // FIXME: we should implement iso_alloc() and iso_activate() unsigned const epn = tu_edpt_number(ep_addr); unsigned const dir_in = tu_edpt_dir(ep_addr); musb_regs_t* musb = MUSB_REGS(rhport); diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 73f63ee2e..1320239c9 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -34,7 +34,8 @@ extern "C" { #include "mxc_device.h" #include "usbhs_regs.h" -#define MUSB_CFG_DYNAMIC_FIFO 0 +#define MUSB_CFG_SHARED_FIFO 1 // shared FIFO for TX and RX endpoints +#define MUSB_CFG_DYNAMIC_FIFO 0 // dynamic EP FIFO sizing const uintptr_t MUSB_BASES[] = { MXC_BASE_USBHS }; @@ -141,24 +142,24 @@ static inline void musb_dcd_phy_init(uint8_t rhport) { hs_phy->m31_phy_ponrst = 1; } -static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { - (void) mps; - - //Most likely the caller has already grabbed the right register block. But - //as a precaution save and restore the register bank anyways - unsigned saved_index = musb_periph_inst[rhport]->index; - - musb_periph_inst[rhport]->index = epnum; - - //Disable double buffering - if (dir_in) { - musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE); - } else { - musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); - } - - musb_periph_inst[rhport]->index = saved_index; -} +// static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { +// (void) mps; +// +// //Most likely the caller has already grabbed the right register block. But +// //as a precaution save and restore the register bank anyways +// unsigned saved_index = musb_periph_inst[rhport]->index; +// +// musb_periph_inst[rhport]->index = epnum; +// +// //Disable double buffering +// if (dir_in) { +// musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE); +// } else { +// musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); +// } +// +// musb_periph_inst[rhport]->index = saved_index; +// } #endif // CFG_TUD_ENABLED diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index e43b3d3c0..7c15b61ad 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -42,6 +42,7 @@ #error "Unsupported MCUs" #endif +#define MUSB_CFG_SHARED_FIFO 0 #define MUSB_CFG_DYNAMIC_FIFO 1 #define MUSB_CFG_DYNAMIC_FIFO_SIZE 4096 @@ -91,6 +92,7 @@ static inline void musb_dcd_int_handler_exit(uint8_t rhport) { //Nothing to do for this part } +#if 0 typedef struct { uint_fast16_t beg; /* offset of including first element */ uint_fast16_t end; /* offset of excluding the last element */ @@ -224,6 +226,7 @@ static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned musb_periph_inst[rhport]->RXFIFOSZ = size_in_log2_minus3; } } +#endif #endif // CFG_TUD_ENABLED diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index ee0187270..08f26edbd 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -261,7 +261,7 @@ typedef struct TU_ATTR_PACKED { //------------- Non-Indexed Endpoint CSRs -------------// // TI tm4c can access this directly, but should use indexed_csr for portability - musb_ep_csr_t ep_csr[16]; // 0x100-0x1FF: EP0-15 CSR + musb_ep_csr_t abs_csr[16]; // 0x100-0x1FF: EP0-15 CSR } musb_regs_t; TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x200, "size is not correct"); @@ -307,6 +307,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // 0x13, 0x17: TX/RX CSRH #define MUSB_CSRH_DISABLE_DOUBLE_PACKET(_rx) (1u << 1) +#define MUSB_CSRH_TX_MODE (1u << 5) // 1 = TX, 0 = RX. only relevant for SHARED FIFO //***************************************************************************** -- cgit v1.3.1 From 993473312b390b722d8693c23310b306997f8c2b Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 17 Aug 2024 17:09:38 +0700 Subject: minor update --- src/portable/mentor/musb/dcd_musb.c | 31 ++++++++++++++++++------------- src/portable/mentor/musb/musb_max32.h | 24 ++++-------------------- src/portable/mentor/musb/musb_ti.h | 5 ----- 3 files changed, 22 insertions(+), 38 deletions(-) diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index e9d907828..3dcb9cdf1 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -29,6 +29,9 @@ #if CFG_TUD_ENABLED && defined(TUP_USBIP_MUSB) +#define MUSB_DEBUG 2 +#define MUSB_REGS(rhport) ((musb_regs_t*) MUSB_BASES[rhport]) + #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) /* GCC warns that an address may be unaligned, even though * the target CPU has the capability for unaligned memory access. */ @@ -49,10 +52,6 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); #error "Unsupported MCU" #endif -#define MUSB_REGS(rhport) ((musb_regs_t*) MUSB_BASES[rhport]) - -#define MUSB_DEBUG 2 - /*------------------------------------------------------------------ * MACRO TYPEDEF CONSTANT ENUM DECLARATION *------------------------------------------------------------------*/ @@ -60,9 +59,9 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); #define REQUEST_TYPE_INVALID (0xFFu) typedef union { - uint8_t u8; - uint16_t u16; - uint32_t u32; + volatile uint8_t u8; + volatile uint16_t u16; + volatile uint32_t u32; } hw_fifo_t; typedef struct TU_ATTR_PACKED @@ -223,11 +222,12 @@ static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigne static void process_setup_packet(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); + + // Read setup packet uint32_t *p = (void*)&_dcd.setup_packet; volatile uint32_t *fifo_ptr = &musb_regs->fifo[0]; - - p[0] = *fifo_ptr; - p[1] = *fifo_ptr; + p[0] = *fifo_ptr; + p[1] = *fifo_ptr; _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; @@ -407,6 +407,7 @@ static void process_ep0(uint8_t rhport) uint_fast8_t csrl = ep_csr->csr0l; // TU_LOG1(" EP0 ep_csr->csr0l = %x\r\n", csrl); + // 21.1.5: endpoint 0 service routine as peripheral if (csrl & USB_CSRL0_STALLED) { /* Returned STALL packet to HOST. */ @@ -705,7 +706,10 @@ void dcd_edpt_close_all(uint8_t rhport) fifo_reset(musb, i, 0); fifo_reset(musb, i, 1); } + +#if MUSB_CFG_DYNAMIC_FIFO alloced_fifo_bytes = CFG_TUD_ENDPOINT0_SIZE; +#endif if (ie) musb_dcd_int_enable(rhport); } @@ -822,10 +826,12 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) * ISR *-------------------------------------------------------------------*/ void dcd_int_handler(uint8_t rhport) { + musb_regs_t* musb_regs = MUSB_REGS(rhport); + const uint8_t saved_index = musb_regs->index; // save endpoint index + //Part specific ISR setup/entry musb_dcd_int_handler_enter(rhport); - musb_regs_t* musb_regs = MUSB_REGS(rhport); uint_fast8_t intr_usb = musb_regs->intr_usb; // a read will clear this interrupt status uint_fast8_t intr_tx = musb_regs->intr_tx; // a read will clear this interrupt status uint_fast8_t intr_rx = musb_regs->intr_rx; // a read will clear this interrupt status @@ -865,8 +871,7 @@ void dcd_int_handler(uint8_t rhport) { intr_rx &= ~TU_BIT(num); } - //Part specific ISR exit - musb_dcd_int_handler_exit(rhport); + musb_regs->index = saved_index; // restore endpoint index } #endif diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 1320239c9..38e80f680 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -42,11 +42,6 @@ const uintptr_t MUSB_BASES[] = { MXC_BASE_USBHS }; #if CFG_TUD_ENABLED #define USBHS_M31_CLOCK_RECOVERY -// Mapping of peripheral instances to port. Currently just 1. -static mxc_usbhs_regs_t* const musb_periph_inst[] = { - MXC_USBHS -}; - // Mapping of IRQ numbers to port. Currently just 1. static const IRQn_Type musb_irqs[] = { USB_IRQn @@ -77,31 +72,21 @@ static inline void musb_dcd_int_clear(uint8_t rhport) { NVIC_ClearPendingIRQ(musb_irqs[rhport]); } -//Used to save and restore user's register map when interrupt occurs -static volatile unsigned isr_saved_index = 0; - static inline void musb_dcd_int_handler_enter(uint8_t rhport) { + mxc_usbhs_regs_t* hs_phy = MXC_USBHS; uint32_t mxm_int, mxm_int_en, mxm_is; - //save current register index - isr_saved_index = musb_periph_inst[rhport]->index; - //Handle PHY specific events - mxm_int = musb_periph_inst[rhport]->mxm_int; - mxm_int_en = musb_periph_inst[rhport]->mxm_int_en; + mxm_int = hs_phy->mxm_int; + mxm_int_en = hs_phy->mxm_int_en; mxm_is = mxm_int & mxm_int_en; - musb_periph_inst[rhport]->mxm_int = mxm_is; + hs_phy->mxm_int = mxm_is; if (mxm_is & MXC_F_USBHS_MXM_INT_NOVBUS) { dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); } } -static inline void musb_dcd_int_handler_exit(uint8_t rhport) { - //restore register index - musb_periph_inst[rhport]->index = isr_saved_index; -} - static inline void musb_dcd_phy_init(uint8_t rhport) { (void) rhport; mxc_usbhs_regs_t* hs_phy = MXC_USBHS; @@ -120,7 +105,6 @@ static inline void musb_dcd_phy_init(uint8_t rhport) { hs_phy->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64); hs_phy->m31_phy_xcfgi_127_96 = 0; - #ifdef USBHS_M31_CLOCK_RECOVERY hs_phy->m31_phy_noncry_rstb = 1; hs_phy->m31_phy_noncry_en = 1; diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index 7c15b61ad..680bebde7 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -87,11 +87,6 @@ static inline void musb_dcd_int_handler_enter(uint8_t rhport) { //Nothing to do for this part } -static inline void musb_dcd_int_handler_exit(uint8_t rhport) { - (void)rhport; - //Nothing to do for this part -} - #if 0 typedef struct { uint_fast16_t beg; /* offset of including first element */ -- cgit v1.3.1 From a6bee747b6f550e4fdb144c7db4aad70fee5ac69 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 17 Aug 2024 18:07:36 +0700 Subject: define and use TUD_ENDPOINT_EXCLUSIVE_NUMBER --- .../device/cdc_dual_ports/src/usb_descriptors.c | 30 ++++------- examples/device/cdc_msc/src/usb_descriptors.c | 27 +--------- .../device/cdc_msc_freertos/src/usb_descriptors.c | 28 +++++----- examples/device/cdc_uac2/src/usb_descriptors.c | 25 +-------- .../dynamic_configuration/src/usb_descriptors.c | 31 +---------- examples/device/midi_test/src/usb_descriptors.c | 30 ++++++----- examples/device/msc_dual_lun/src/usb_descriptors.c | 27 ++++------ .../net_lwip_webserver/src/usb_descriptors.c | 15 +++--- examples/device/uac2_headset/src/usb_descriptors.c | 26 ++++----- .../device/uac2_speaker_fb/src/usb_descriptors.c | 11 +--- .../device/webusb_serial/src/usb_descriptors.c | 63 +++++++++++----------- src/common/tusb_mcu.h | 13 +++-- 12 files changed, 113 insertions(+), 213 deletions(-) diff --git a/examples/device/cdc_dual_ports/src/usb_descriptors.c b/examples/device/cdc_dual_ports/src/usb_descriptors.c index 808d78411..ca4fe279b 100644 --- a/examples/device/cdc_dual_ports/src/usb_descriptors.c +++ b/examples/device/cdc_dual_ports/src/usb_descriptors.c @@ -98,31 +98,19 @@ enum #define EPNUM_CDC_1_OUT 0x05 #define EPNUM_CDC_1_IN 0x85 -#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X - // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_CDC_0_NOTIF 0x81 +#elif CFG_TUSB_MCU == OPT_MCU_CXD56 + // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number + // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) + #define EPNUM_CDC_0_NOTIF 0x83 #define EPNUM_CDC_0_OUT 0x02 - #define EPNUM_CDC_0_IN 0x83 + #define EPNUM_CDC_0_IN 0x81 - #define EPNUM_CDC_1_NOTIF 0x84 + #define EPNUM_CDC_1_NOTIF 0x86 #define EPNUM_CDC_1_OUT 0x05 - #define EPNUM_CDC_1_IN 0x86 - -#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X - // FT9XX doesn't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_CDC_0_NOTIF 0x81 - #define EPNUM_CDC_0_OUT 0x02 - #define EPNUM_CDC_0_IN 0x83 - - #define EPNUM_CDC_1_NOTIF 0x84 - #define EPNUM_CDC_1_OUT 0x05 - #define EPNUM_CDC_1_IN 0x86 + #define EPNUM_CDC_1_IN 0x84 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ - CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 - // MAX32 doesn't support a same endpoint number with different direction IN and OUT +#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) + // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_0_NOTIF 0x81 #define EPNUM_CDC_0_OUT 0x02 diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c index fac7cce8f..4789f5a9b 100644 --- a/examples/device/cdc_msc/src/usb_descriptors.c +++ b/examples/device/cdc_msc/src/usb_descriptors.c @@ -93,19 +93,7 @@ enum { #define EPNUM_MSC_OUT 0x05 #define EPNUM_MSC_IN 0x85 -#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X - // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_CDC_NOTIF 0x81 - #define EPNUM_CDC_OUT 0x02 - #define EPNUM_CDC_IN 0x83 - - #define EPNUM_MSC_OUT 0x04 - #define EPNUM_MSC_IN 0x85 - #elif CFG_TUSB_MCU == OPT_MCU_CXD56 - // CXD56 doesn't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) #define EPNUM_CDC_NOTIF 0x83 @@ -115,19 +103,8 @@ enum { #define EPNUM_MSC_OUT 0x05 #define EPNUM_MSC_IN 0x84 -#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X - // FT9XX doesn't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_CDC_NOTIF 0x81 - #define EPNUM_CDC_OUT 0x02 - #define EPNUM_CDC_IN 0x83 - - #define EPNUM_MSC_OUT 0x04 - #define EPNUM_MSC_IN 0x85 - -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ - CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 - // MAX32 doesn't support a same endpoint number with different direction IN and OUT +#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) + // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 diff --git a/examples/device/cdc_msc_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_freertos/src/usb_descriptors.c index 917b73e10..7f9338753 100644 --- a/examples/device/cdc_msc_freertos/src/usb_descriptors.c +++ b/examples/device/cdc_msc_freertos/src/usb_descriptors.c @@ -42,8 +42,7 @@ //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = -{ +tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, @@ -69,8 +68,7 @@ tusb_desc_device_t const desc_device = // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor -uint8_t const * tud_descriptor_device_cb(void) -{ +uint8_t const *tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } @@ -78,8 +76,7 @@ uint8_t const * tud_descriptor_device_cb(void) // Configuration Descriptor //--------------------------------------------------------------------+ -enum -{ +enum { ITF_NUM_CDC = 0, ITF_NUM_CDC_DATA, ITF_NUM_MSC, @@ -96,19 +93,18 @@ enum #define EPNUM_MSC_OUT 0x05 #define EPNUM_MSC_IN 0x85 -#elif CFG_TUSB_MCU == OPT_MCU_SAMG - // SAMG doesn't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_CDC_NOTIF 0x81 +#elif CFG_TUSB_MCU == OPT_MCU_CXD56 + // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number + // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) + #define EPNUM_CDC_NOTIF 0x83 #define EPNUM_CDC_OUT 0x02 - #define EPNUM_CDC_IN 0x83 + #define EPNUM_CDC_IN 0x81 - #define EPNUM_MSC_OUT 0x04 - #define EPNUM_MSC_IN 0x85 + #define EPNUM_MSC_OUT 0x05 + #define EPNUM_MSC_IN 0x84 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ - CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 - // MAX32 doesn't support a same endpoint number with different direction IN and OUT +#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) + // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 diff --git a/examples/device/cdc_uac2/src/usb_descriptors.c b/examples/device/cdc_uac2/src/usb_descriptors.c index ab1a2ee83..6384f722a 100644 --- a/examples/device/cdc_uac2/src/usb_descriptors.c +++ b/examples/device/cdc_uac2/src/usb_descriptors.c @@ -97,29 +97,8 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 -#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X - // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_AUDIO_IN 0x01 - #define EPNUM_AUDIO_OUT 0x02 - - #define EPNUM_CDC_NOTIF 0x83 - #define EPNUM_CDC_OUT 0x04 - #define EPNUM_CDC_IN 0x85 - -#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X - // FT9XX doesn't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_AUDIO_IN 0x01 - #define EPNUM_AUDIO_OUT 0x02 - - #define EPNUM_CDC_NOTIF 0x83 - #define EPNUM_CDC_OUT 0x04 - #define EPNUM_CDC_IN 0x85 - -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ - CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 - // MAX32 doesn't support a same endpoint number with different direction IN and OUT +#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) + // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x02 diff --git a/examples/device/dynamic_configuration/src/usb_descriptors.c b/examples/device/dynamic_configuration/src/usb_descriptors.c index 20f237155..7be3d7da5 100644 --- a/examples/device/dynamic_configuration/src/usb_descriptors.c +++ b/examples/device/dynamic_configuration/src/usb_descriptors.c @@ -132,35 +132,8 @@ enum #define EPNUM_1_MSC_OUT 0x02 #define EPNUM_1_MSC_IN 0x82 -#elif CFG_TUSB_MCU == OPT_MCU_SAMG - // SAMG doesn't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_0_CDC_NOTIF 0x81 - #define EPNUM_0_CDC_OUT 0x02 - #define EPNUM_0_CDC_IN 0x83 - - #define EPNUM_0_MIDI_OUT 0x04 - #define EPNUM_0_MIDI_IN 0x85 - - #define EPNUM_1_MSC_OUT 0x01 - #define EPNUM_1_MSC_IN 0x82 - -#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X - // FT9XX doesn't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_0_CDC_NOTIF 0x81 - #define EPNUM_0_CDC_OUT 0x02 - #define EPNUM_0_CDC_IN 0x83 - - #define EPNUM_0_MIDI_OUT 0x04 - #define EPNUM_0_MIDI_IN 0x85 - - #define EPNUM_1_MSC_OUT 0x01 - #define EPNUM_1_MSC_IN 0x82 - -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ - CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 - // FT9XX doesn't support a same endpoint number with different direction IN and OUT +#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) + // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_0_CDC_NOTIF 0x81 #define EPNUM_0_CDC_OUT 0x02 diff --git a/examples/device/midi_test/src/usb_descriptors.c b/examples/device/midi_test/src/usb_descriptors.c index 41e6e1818..3511f7eba 100644 --- a/examples/device/midi_test/src/usb_descriptors.c +++ b/examples/device/midi_test/src/usb_descriptors.c @@ -84,20 +84,24 @@ enum #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... - #define EPNUM_MIDI_OUT 0x02 - #define EPNUM_MIDI_IN 0x02 -#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X - // On Bridgetek FT9xx endpoint numbers must be unique... - #define EPNUM_MIDI_OUT 0x02 - #define EPNUM_MIDI_IN 0x03 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ - CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 - // On MAX32 endpoint numbers must be unique... - #define EPNUM_MIDI_OUT 0x02 - #define EPNUM_MIDI_IN 0x03 + #define EPNUM_MIDI_OUT 0x02 + #define EPNUM_MIDI_IN 0x82 + +#elif CFG_TUSB_MCU == OPT_MCU_CXD56 + // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number + // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) + #define EPNUM_MIDI_OUT 0x02 + #define EPNUM_MIDI_IN 0x81 + +#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) + // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_MIDI_OUT 0x01 + #define EPNUM_MIDI_IN 0x82 + #else - #define EPNUM_MIDI_OUT 0x01 - #define EPNUM_MIDI_IN 0x01 + #define EPNUM_MIDI_OUT 0x01 + #define EPNUM_MIDI_IN 0x81 #endif uint8_t const desc_fs_configuration[] = diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c index c55bab0d8..bc2f2577c 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -85,24 +85,17 @@ enum #define EPNUM_MSC_OUT 0x02 #define EPNUM_MSC_IN 0x82 -#elif CFG_TUSB_MCU == OPT_MCU_SAMG - // SAMG doesn't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_MSC_OUT 0x01 - #define EPNUM_MSC_IN 0x82 - -#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X - // FT9XX doesn't support a same endpoint number with different direction IN and OUT +#elif CFG_TUSB_MCU == OPT_MCU_CXD56 + // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number + // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) + #define EPNUM_MSC_OUT 0x02 + #define EPNUM_MSC_IN 0x81 + +#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) + // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_MSC_OUT 0x01 - #define EPNUM_MSC_IN 0x82 - -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ - CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 - // MAX32 doesn't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_MSC_OUT 0x01 - #define EPNUM_MSC_IN 0x82 + #define EPNUM_MSC_OUT 0x01 + #define EPNUM_MSC_IN 0x82 #else #define EPNUM_MSC_OUT 0x01 diff --git a/examples/device/net_lwip_webserver/src/usb_descriptors.c b/examples/device/net_lwip_webserver/src/usb_descriptors.c index 012e1bcd8..2a3061162 100644 --- a/examples/device/net_lwip_webserver/src/usb_descriptors.c +++ b/examples/device/net_lwip_webserver/src/usb_descriptors.c @@ -113,16 +113,15 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_NET_OUT 0x02 #define EPNUM_NET_IN 0x82 -#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X - // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_NET_NOTIF 0x81 +#elif CFG_TUSB_MCU == OPT_MCU_CXD56 + // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number + // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) + #define EPNUM_NET_NOTIF 0x83 #define EPNUM_NET_OUT 0x02 - #define EPNUM_NET_IN 0x83 + #define EPNUM_NET_IN 0x81 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ - CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 - // MAX32 doesn't support a same endpoint number with different direction IN and OUT +#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) + // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_NET_NOTIF 0x81 #define EPNUM_NET_OUT 0x02 diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c index a042ad206..e8dc5ec15 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -84,29 +84,21 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_AUDIO_OUT 0x03 #define EPNUM_AUDIO_INT 0x01 +#elif CFG_TUSB_MCU == OPT_MCU_CXD56 + // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number + // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) + // #define EPNUM_AUDIO_IN 0x01 + // #define EPNUM_AUDIO_OUT 0x02 + // #define EPNUM_AUDIO_INT 0x03 + #elif CFG_TUSB_MCU == OPT_MCU_NRF5X // ISO endpoints for NRF5x are fixed to 0x08 (0x88) #define EPNUM_AUDIO_IN 0x08 #define EPNUM_AUDIO_OUT 0x08 #define EPNUM_AUDIO_INT 0x01 -#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X - // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_AUDIO_IN 0x01 - #define EPNUM_AUDIO_OUT 0x02 - #define EPNUM_AUDIO_INT 0x03 - -#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X - // FT9XX doesn't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_AUDIO_IN 0x01 - #define EPNUM_AUDIO_OUT 0x02 - #define EPNUM_AUDIO_INT 0x03 - -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ - CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 - // MAX32 doesn't support a same endpoint number with different direction IN and OUT +#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) + // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x02 diff --git a/examples/device/uac2_speaker_fb/src/usb_descriptors.c b/examples/device/uac2_speaker_fb/src/usb_descriptors.c index 31c5e116d..aadeb7e8a 100644 --- a/examples/device/uac2_speaker_fb/src/usb_descriptors.c +++ b/examples/device/uac2_speaker_fb/src/usb_descriptors.c @@ -131,15 +131,8 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf) #define EPNUM_AUDIO_OUT 0x08 #define EPNUM_DEBUG 0x01 -#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X - // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_AUDIO_FB 0x01 - #define EPNUM_AUDIO_OUT 0x02 - #define EPNUM_DEBUG 0x03 - -#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X - // FT9XX doesn't support a same endpoint number with different direction IN and OUT +#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) + // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_AUDIO_FB 0x01 #define EPNUM_AUDIO_OUT 0x02 diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c index ae1051af6..2ff6d9ced 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.c +++ b/examples/device/webusb_serial/src/usb_descriptors.c @@ -87,37 +87,40 @@ enum #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... - #define EPNUM_CDC_IN 2 - #define EPNUM_CDC_OUT 2 - #define EPNUM_VENDOR_IN 5 - #define EPNUM_VENDOR_OUT 5 -#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X - // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_CDC_IN 2 - #define EPNUM_CDC_OUT 3 - #define EPNUM_VENDOR_IN 4 - #define EPNUM_VENDOR_OUT 5 -#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X - // FT9XX doesn't support a same endpoint number with different direction IN and OUT - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_CDC_IN 2 - #define EPNUM_CDC_OUT 3 - #define EPNUM_VENDOR_IN 4 - #define EPNUM_VENDOR_OUT 5 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ - CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 - // MAX32 doesn't support a same endpoint number with different direction IN and OUT + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x82 + + #define EPNUM_VENDOR_OUT 0x05 + #define EPNUM_VENDOR_IN 0x85 + +#elif CFG_TUSB_MCU == OPT_MCU_CXD56 + // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number + // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) + #define EPNUM_CDC_NOTIF 0x83 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x81 + + #define EPNUM_VENDOR_OUT 0x05 + #define EPNUM_VENDOR_IN 0x84 + +#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) + // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_CDC_IN 2 - #define EPNUM_CDC_OUT 3 - #define EPNUM_VENDOR_IN 4 - #define EPNUM_VENDOR_OUT 5 + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x83 + + #define EPNUM_VENDOR_OUT 0x04 + #define EPNUM_VENDOR_IN 0x85 + #else - #define EPNUM_CDC_IN 2 - #define EPNUM_CDC_OUT 2 - #define EPNUM_VENDOR_IN 3 - #define EPNUM_VENDOR_OUT 3 + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x82 + + #define EPNUM_VENDOR_OUT 0x03 + #define EPNUM_VENDOR_IN 0x83 #endif uint8_t const desc_configuration[] = @@ -126,7 +129,7 @@ uint8_t const desc_configuration[] = TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. - TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, 0x81, 8, EPNUM_CDC_OUT, 0x80 | EPNUM_CDC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), + TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, 0x80 | EPNUM_CDC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), // Interface number, string index, EP Out & IN address, EP size TUD_VENDOR_DESCRIPTOR(ITF_NUM_VENDOR, 5, EPNUM_VENDOR_OUT, 0x80 | EPNUM_VENDOR_IN, TUD_OPT_HIGH_SPEED ? 512 : 64) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 0180fc466..b7cbd83df 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -138,21 +138,21 @@ #elif TU_CHECK_MCU(OPT_MCU_SAMG) #define TUP_DCD_ENDPOINT_MAX 6 - #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER + #define TUD_ENDPOINT_EXCLUSIVE_NUMBER #elif TU_CHECK_MCU(OPT_MCU_SAMX7X) #define TUP_DCD_ENDPOINT_MAX 10 #define TUP_RHPORT_HIGHSPEED 1 - #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER + #define TUD_ENDPOINT_EXCLUSIVE_NUMBER #elif TU_CHECK_MCU(OPT_MCU_PIC32MZ) #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER + #define TUD_ENDPOINT_EXCLUSIVE_NUMBER #elif TU_CHECK_MCU(OPT_MCU_PIC32MX, OPT_MCU_PIC32MM, OPT_MCU_PIC32MK) || \ TU_CHECK_MCU(OPT_MCU_PIC24, OPT_MCU_DSPIC33) #define TUP_DCD_ENDPOINT_MAX 16 - #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER + #define TUD_ENDPOINT_EXCLUSIVE_NUMBER //--------------------------------------------------------------------+ // ST @@ -299,7 +299,7 @@ #elif TU_CHECK_MCU(OPT_MCU_CXD56) #define TUP_DCD_ENDPOINT_MAX 7 #define TUP_RHPORT_HIGHSPEED 1 - #define TUP_DCD_ENDPOINT_EXCLUSIVE_NUMBER + #define TUD_ENDPOINT_EXCLUSIVE_NUMBER //--------------------------------------------------------------------+ // TI @@ -400,10 +400,12 @@ #elif TU_CHECK_MCU(OPT_MCU_FT90X) #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_RHPORT_HIGHSPEED 1 + #define TUD_ENDPOINT_EXCLUSIVE_NUMBER #elif TU_CHECK_MCU(OPT_MCU_FT93X) #define TUP_DCD_ENDPOINT_MAX 16 #define TUP_RHPORT_HIGHSPEED 1 + #define TUD_ENDPOINT_EXCLUSIVE_NUMBER //--------------------------------------------------------------------+ // Allwinner @@ -478,6 +480,7 @@ #define TUP_USBIP_MUSB_ADI #define TUP_DCD_ENDPOINT_MAX 12 #define TUP_RHPORT_HIGHSPEED 1 + #define TUD_ENDPOINT_EXCLUSIVE_NUMBER #endif -- cgit v1.3.1 From 123830c1f00813d86d0405dc7a5624ccb1220a31 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 17 Aug 2024 19:06:19 +0700 Subject: remove unused register def --- src/portable/mentor/musb/musb_type.h | 1594 ++-------------------------------- 1 file changed, 59 insertions(+), 1535 deletions(-) diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 08f26edbd..619eb0108 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -262,9 +262,37 @@ typedef struct TU_ATTR_PACKED { //------------- Non-Indexed Endpoint CSRs -------------// // TI tm4c can access this directly, but should use indexed_csr for portability musb_ep_csr_t abs_csr[16]; // 0x100-0x1FF: EP0-15 CSR + + //------------- DMA -------------// + __IO uint8_t dma_intr; // 0x200: DMA_INTR + __R uint8_t rsv_0x201_0x203[3]; // 0x201-0x203: Reserved + struct { + __IO uint16_t cntl; // 0x204: DMA_CNTL + __IO uint16_t rsv_0x206; // 0x206: Reserved + __IO uint32_t addr; // 0x208: DMA_ADDR + __IO uint32_t count; // 0x20C: DMA_COUNT + __IO uint32_t rsv_0x210; // 0x210: Reserved + }dma[8]; + __R uint32_t rsv_0x284_0x2FF[31]; // 0x284-0x2FF: Reserved + + //------------- Extended -------------// + __R uint32_t rsv_0x300; // 0x300: Reserved + struct { + __IO uint16_t count; // 0x304: REQ_PACKET_COUNT + __R uint16_t rsv_0x306; // 0x306: Reserved + }req_packet[15]; + + __IO uint16_t rx_doulbe_packet_disable; // 0x340: RX_DOUBLE_PACKET_DISABLE + __IO uint16_t tx_double_packet_disable; // 0x342: TX_DOUBLE_PACKET_DISABLE + + __IO uint16_t chirp_timeout; // 0x344: CHIRP_TIMEOUT + __IO uint16_t hs_to_utm; // 0x346: HS_TO_UTM delay + __IO uint16_t hs_timeout_adder; // 0x348: HS_TIMEOUT_ADDER + + __R uint8_t rsv_34A_34f[6]; // 0x34A-0x34F: Reserved } musb_regs_t; -TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x200, "size is not correct"); +TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x350, "size is not correct"); //--------------------------------------------------------------------+ // Helper @@ -566,14 +594,6 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ #define USB_CSRH0_DT 0x0002 // Data Toggle #define USB_CSRH0_FLUSH 0x0001 // Flush FIFO -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_COUNT0 register. -// -//***************************************************************************** -#define USB_COUNT0_COUNT_M 0x007F // FIFO Count -#define USB_COUNT0_COUNT_S 0 - //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TYPE0 register. @@ -592,14 +612,6 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ #define USB_NAKLMT_NAKLMT_M 0x001F // EP0 NAK Limit #define USB_NAKLMT_NAKLMT_S 0 -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXMAXP1 register. -// -//***************************************************************************** -#define USB_TXMAXP1_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_TXMAXP1_MAXLOAD_S 0 - //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRL1 register. @@ -630,14 +642,6 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ #define USB_TXCSRH1_DTWE 0x0002 // Data Toggle Write Enable #define USB_TXCSRH1_DT 0x0001 // Data Toggle -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXMAXP1 register. -// -//***************************************************************************** -#define USB_RXMAXP1_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_RXMAXP1_MAXLOAD_S 0 - //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRL1 register. @@ -669,16 +673,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ #define USB_RXCSRH1_DMAMOD 0x0008 // DMA Request Mode #define USB_RXCSRH1_DTWE 0x0004 // Data Toggle Write Enable #define USB_RXCSRH1_DT 0x0002 // Data Toggle -#define USB_RXCSRH1_INCOMPRX 0x0001 // Incomplete RX Transmission - // Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCOUNT1 register. -// -//***************************************************************************** -#define USB_RXCOUNT1_COUNT_M 0x1FFF // Receive Packet Count -#define USB_RXCOUNT1_COUNT_S 0 +#define USB_RXCSRH1_INCOMPRX 0x0001 // Incomplete RX Transmission Status //***************************************************************************** // @@ -740,1537 +735,66 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXMAXP2 register. -// -//***************************************************************************** -#define USB_TXMAXP2_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_TXMAXP2_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRL2 register. -// -//***************************************************************************** -#define USB_TXCSRL2_NAKTO 0x0080 // NAK Timeout -#define USB_TXCSRL2_CLRDT 0x0040 // Clear Data Toggle -#define USB_TXCSRL2_STALLED 0x0020 // Endpoint Stalled -#define USB_TXCSRL2_SETUP 0x0010 // Setup Packet -#define USB_TXCSRL2_STALL 0x0010 // Send STALL -#define USB_TXCSRL2_FLUSH 0x0008 // Flush FIFO -#define USB_TXCSRL2_ERROR 0x0004 // Error -#define USB_TXCSRL2_UNDRN 0x0004 // Underrun -#define USB_TXCSRL2_FIFONE 0x0002 // FIFO Not Empty -#define USB_TXCSRL2_TXRDY 0x0001 // Transmit Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRH2 register. -// -//***************************************************************************** -#define USB_TXCSRH2_AUTOSET 0x0080 // Auto Set -#define USB_TXCSRH2_ISO 0x0040 // Isochronous Transfers -#define USB_TXCSRH2_MODE 0x0020 // Mode -#define USB_TXCSRH2_DMAEN 0x0010 // DMA Request Enable -#define USB_TXCSRH2_FDT 0x0008 // Force Data Toggle -#define USB_TXCSRH2_DMAMOD 0x0004 // DMA Request Mode -#define USB_TXCSRH2_DTWE 0x0002 // Data Toggle Write Enable -#define USB_TXCSRH2_DT 0x0001 // Data Toggle - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXMAXP2 register. -// -//***************************************************************************** -#define USB_RXMAXP2_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_RXMAXP2_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRL2 register. -// -//***************************************************************************** -#define USB_RXCSRL2_CLRDT 0x0080 // Clear Data Toggle -#define USB_RXCSRL2_STALLED 0x0040 // Endpoint Stalled -#define USB_RXCSRL2_REQPKT 0x0020 // Request Packet -#define USB_RXCSRL2_STALL 0x0020 // Send STALL -#define USB_RXCSRL2_FLUSH 0x0010 // Flush FIFO -#define USB_RXCSRL2_DATAERR 0x0008 // Data Error -#define USB_RXCSRL2_NAKTO 0x0008 // NAK Timeout -#define USB_RXCSRL2_ERROR 0x0004 // Error -#define USB_RXCSRL2_OVER 0x0004 // Overrun -#define USB_RXCSRL2_FULL 0x0002 // FIFO Full -#define USB_RXCSRL2_RXRDY 0x0001 // Receive Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRH2 register. -// -//***************************************************************************** -#define USB_RXCSRH2_AUTOCL 0x0080 // Auto Clear -#define USB_RXCSRH2_AUTORQ 0x0040 // Auto Request -#define USB_RXCSRH2_ISO 0x0040 // Isochronous Transfers -#define USB_RXCSRH2_DMAEN 0x0020 // DMA Request Enable -#define USB_RXCSRH2_DISNYET 0x0010 // Disable NYET -#define USB_RXCSRH2_PIDERR 0x0010 // PID Error -#define USB_RXCSRH2_DMAMOD 0x0008 // DMA Request Mode -#define USB_RXCSRH2_DTWE 0x0004 // Data Toggle Write Enable -#define USB_RXCSRH2_DT 0x0002 // Data Toggle -#define USB_RXCSRH2_INCOMPRX 0x0001 // Incomplete RX Transmission - // Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCOUNT2 register. -// -//***************************************************************************** -#define USB_RXCOUNT2_COUNT_M 0x1FFF // Receive Packet Count -#define USB_RXCOUNT2_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXTYPE2 register. -// -//***************************************************************************** -#define USB_TXTYPE2_SPEED_M 0x00C0 // Operating Speed -#define USB_TXTYPE2_SPEED_DFLT 0x0000 // Default -#define USB_TXTYPE2_SPEED_HIGH 0x0040 // High -#define USB_TXTYPE2_SPEED_FULL 0x0080 // Full -#define USB_TXTYPE2_SPEED_LOW 0x00C0 // Low -#define USB_TXTYPE2_PROTO_M 0x0030 // Protocol -#define USB_TXTYPE2_PROTO_CTRL 0x0000 // Control -#define USB_TXTYPE2_PROTO_ISOC 0x0010 // Isochronous -#define USB_TXTYPE2_PROTO_BULK 0x0020 // Bulk -#define USB_TXTYPE2_PROTO_INT 0x0030 // Interrupt -#define USB_TXTYPE2_TEP_M 0x000F // Target Endpoint Number -#define USB_TXTYPE2_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXINTERVAL2 -// register. -// -//***************************************************************************** -#define USB_TXINTERVAL2_TXPOLL_M 0x00FF // TX Polling -#define USB_TXINTERVAL2_NAKLMT_M 0x00FF // NAK Limit -#define USB_TXINTERVAL2_NAKLMT_S 0 -#define USB_TXINTERVAL2_TXPOLL_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXTYPE2 register. -// -//***************************************************************************** -#define USB_RXTYPE2_SPEED_M 0x00C0 // Operating Speed -#define USB_RXTYPE2_SPEED_DFLT 0x0000 // Default -#define USB_RXTYPE2_SPEED_HIGH 0x0040 // High -#define USB_RXTYPE2_SPEED_FULL 0x0080 // Full -#define USB_RXTYPE2_SPEED_LOW 0x00C0 // Low -#define USB_RXTYPE2_PROTO_M 0x0030 // Protocol -#define USB_RXTYPE2_PROTO_CTRL 0x0000 // Control -#define USB_RXTYPE2_PROTO_ISOC 0x0010 // Isochronous -#define USB_RXTYPE2_PROTO_BULK 0x0020 // Bulk -#define USB_RXTYPE2_PROTO_INT 0x0030 // Interrupt -#define USB_RXTYPE2_TEP_M 0x000F // Target Endpoint Number -#define USB_RXTYPE2_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXINTERVAL2 -// register. -// -//***************************************************************************** -#define USB_RXINTERVAL2_TXPOLL_M 0x00FF // RX Polling -#define USB_RXINTERVAL2_NAKLMT_M 0x00FF // NAK Limit -#define USB_RXINTERVAL2_TXPOLL_S 0 -#define USB_RXINTERVAL2_NAKLMT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXMAXP3 register. -// -//***************************************************************************** -#define USB_TXMAXP3_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_TXMAXP3_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRL3 register. -// -//***************************************************************************** -#define USB_TXCSRL3_NAKTO 0x0080 // NAK Timeout -#define USB_TXCSRL3_CLRDT 0x0040 // Clear Data Toggle -#define USB_TXCSRL3_STALLED 0x0020 // Endpoint Stalled -#define USB_TXCSRL3_SETUP 0x0010 // Setup Packet -#define USB_TXCSRL3_STALL 0x0010 // Send STALL -#define USB_TXCSRL3_FLUSH 0x0008 // Flush FIFO -#define USB_TXCSRL3_ERROR 0x0004 // Error -#define USB_TXCSRL3_UNDRN 0x0004 // Underrun -#define USB_TXCSRL3_FIFONE 0x0002 // FIFO Not Empty -#define USB_TXCSRL3_TXRDY 0x0001 // Transmit Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRH3 register. -// -//***************************************************************************** -#define USB_TXCSRH3_AUTOSET 0x0080 // Auto Set -#define USB_TXCSRH3_ISO 0x0040 // Isochronous Transfers -#define USB_TXCSRH3_MODE 0x0020 // Mode -#define USB_TXCSRH3_DMAEN 0x0010 // DMA Request Enable -#define USB_TXCSRH3_FDT 0x0008 // Force Data Toggle -#define USB_TXCSRH3_DMAMOD 0x0004 // DMA Request Mode -#define USB_TXCSRH3_DTWE 0x0002 // Data Toggle Write Enable -#define USB_TXCSRH3_DT 0x0001 // Data Toggle - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXMAXP3 register. -// -//***************************************************************************** -#define USB_RXMAXP3_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_RXMAXP3_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRL3 register. -// -//***************************************************************************** -#define USB_RXCSRL3_CLRDT 0x0080 // Clear Data Toggle -#define USB_RXCSRL3_STALLED 0x0040 // Endpoint Stalled -#define USB_RXCSRL3_STALL 0x0020 // Send STALL -#define USB_RXCSRL3_REQPKT 0x0020 // Request Packet -#define USB_RXCSRL3_FLUSH 0x0010 // Flush FIFO -#define USB_RXCSRL3_DATAERR 0x0008 // Data Error -#define USB_RXCSRL3_NAKTO 0x0008 // NAK Timeout -#define USB_RXCSRL3_ERROR 0x0004 // Error -#define USB_RXCSRL3_OVER 0x0004 // Overrun -#define USB_RXCSRL3_FULL 0x0002 // FIFO Full -#define USB_RXCSRL3_RXRDY 0x0001 // Receive Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRH3 register. -// -//***************************************************************************** -#define USB_RXCSRH3_AUTOCL 0x0080 // Auto Clear -#define USB_RXCSRH3_AUTORQ 0x0040 // Auto Request -#define USB_RXCSRH3_ISO 0x0040 // Isochronous Transfers -#define USB_RXCSRH3_DMAEN 0x0020 // DMA Request Enable -#define USB_RXCSRH3_DISNYET 0x0010 // Disable NYET -#define USB_RXCSRH3_PIDERR 0x0010 // PID Error -#define USB_RXCSRH3_DMAMOD 0x0008 // DMA Request Mode -#define USB_RXCSRH3_DTWE 0x0004 // Data Toggle Write Enable -#define USB_RXCSRH3_DT 0x0002 // Data Toggle -#define USB_RXCSRH3_INCOMPRX 0x0001 // Incomplete RX Transmission - // Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCOUNT3 register. -// -//***************************************************************************** -#define USB_RXCOUNT3_COUNT_M 0x1FFF // Receive Packet Count -#define USB_RXCOUNT3_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXTYPE3 register. -// -//***************************************************************************** -#define USB_TXTYPE3_SPEED_M 0x00C0 // Operating Speed -#define USB_TXTYPE3_SPEED_DFLT 0x0000 // Default -#define USB_TXTYPE3_SPEED_HIGH 0x0040 // High -#define USB_TXTYPE3_SPEED_FULL 0x0080 // Full -#define USB_TXTYPE3_SPEED_LOW 0x00C0 // Low -#define USB_TXTYPE3_PROTO_M 0x0030 // Protocol -#define USB_TXTYPE3_PROTO_CTRL 0x0000 // Control -#define USB_TXTYPE3_PROTO_ISOC 0x0010 // Isochronous -#define USB_TXTYPE3_PROTO_BULK 0x0020 // Bulk -#define USB_TXTYPE3_PROTO_INT 0x0030 // Interrupt -#define USB_TXTYPE3_TEP_M 0x000F // Target Endpoint Number -#define USB_TXTYPE3_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXINTERVAL3 -// register. -// -//***************************************************************************** -#define USB_TXINTERVAL3_TXPOLL_M 0x00FF // TX Polling -#define USB_TXINTERVAL3_NAKLMT_M 0x00FF // NAK Limit -#define USB_TXINTERVAL3_TXPOLL_S 0 -#define USB_TXINTERVAL3_NAKLMT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXTYPE3 register. -// -//***************************************************************************** -#define USB_RXTYPE3_SPEED_M 0x00C0 // Operating Speed -#define USB_RXTYPE3_SPEED_DFLT 0x0000 // Default -#define USB_RXTYPE3_SPEED_HIGH 0x0040 // High -#define USB_RXTYPE3_SPEED_FULL 0x0080 // Full -#define USB_RXTYPE3_SPEED_LOW 0x00C0 // Low -#define USB_RXTYPE3_PROTO_M 0x0030 // Protocol -#define USB_RXTYPE3_PROTO_CTRL 0x0000 // Control -#define USB_RXTYPE3_PROTO_ISOC 0x0010 // Isochronous -#define USB_RXTYPE3_PROTO_BULK 0x0020 // Bulk -#define USB_RXTYPE3_PROTO_INT 0x0030 // Interrupt -#define USB_RXTYPE3_TEP_M 0x000F // Target Endpoint Number -#define USB_RXTYPE3_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXINTERVAL3 -// register. -// -//***************************************************************************** -#define USB_RXINTERVAL3_TXPOLL_M 0x00FF // RX Polling -#define USB_RXINTERVAL3_NAKLMT_M 0x00FF // NAK Limit -#define USB_RXINTERVAL3_TXPOLL_S 0 -#define USB_RXINTERVAL3_NAKLMT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXMAXP4 register. -// -//***************************************************************************** -#define USB_TXMAXP4_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_TXMAXP4_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRL4 register. -// -//***************************************************************************** -#define USB_TXCSRL4_NAKTO 0x0080 // NAK Timeout -#define USB_TXCSRL4_CLRDT 0x0040 // Clear Data Toggle -#define USB_TXCSRL4_STALLED 0x0020 // Endpoint Stalled -#define USB_TXCSRL4_SETUP 0x0010 // Setup Packet -#define USB_TXCSRL4_STALL 0x0010 // Send STALL -#define USB_TXCSRL4_FLUSH 0x0008 // Flush FIFO -#define USB_TXCSRL4_ERROR 0x0004 // Error -#define USB_TXCSRL4_UNDRN 0x0004 // Underrun -#define USB_TXCSRL4_FIFONE 0x0002 // FIFO Not Empty -#define USB_TXCSRL4_TXRDY 0x0001 // Transmit Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRH4 register. -// -//***************************************************************************** -#define USB_TXCSRH4_AUTOSET 0x0080 // Auto Set -#define USB_TXCSRH4_ISO 0x0040 // Isochronous Transfers -#define USB_TXCSRH4_MODE 0x0020 // Mode -#define USB_TXCSRH4_DMAEN 0x0010 // DMA Request Enable -#define USB_TXCSRH4_FDT 0x0008 // Force Data Toggle -#define USB_TXCSRH4_DMAMOD 0x0004 // DMA Request Mode -#define USB_TXCSRH4_DTWE 0x0002 // Data Toggle Write Enable -#define USB_TXCSRH4_DT 0x0001 // Data Toggle - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXMAXP4 register. -// -//***************************************************************************** -#define USB_RXMAXP4_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_RXMAXP4_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRL4 register. -// -//***************************************************************************** -#define USB_RXCSRL4_CLRDT 0x0080 // Clear Data Toggle -#define USB_RXCSRL4_STALLED 0x0040 // Endpoint Stalled -#define USB_RXCSRL4_STALL 0x0020 // Send STALL -#define USB_RXCSRL4_REQPKT 0x0020 // Request Packet -#define USB_RXCSRL4_FLUSH 0x0010 // Flush FIFO -#define USB_RXCSRL4_NAKTO 0x0008 // NAK Timeout -#define USB_RXCSRL4_DATAERR 0x0008 // Data Error -#define USB_RXCSRL4_OVER 0x0004 // Overrun -#define USB_RXCSRL4_ERROR 0x0004 // Error -#define USB_RXCSRL4_FULL 0x0002 // FIFO Full -#define USB_RXCSRL4_RXRDY 0x0001 // Receive Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRH4 register. -// -//***************************************************************************** -#define USB_RXCSRH4_AUTOCL 0x0080 // Auto Clear -#define USB_RXCSRH4_AUTORQ 0x0040 // Auto Request -#define USB_RXCSRH4_ISO 0x0040 // Isochronous Transfers -#define USB_RXCSRH4_DMAEN 0x0020 // DMA Request Enable -#define USB_RXCSRH4_DISNYET 0x0010 // Disable NYET -#define USB_RXCSRH4_PIDERR 0x0010 // PID Error -#define USB_RXCSRH4_DMAMOD 0x0008 // DMA Request Mode -#define USB_RXCSRH4_DTWE 0x0004 // Data Toggle Write Enable -#define USB_RXCSRH4_DT 0x0002 // Data Toggle -#define USB_RXCSRH4_INCOMPRX 0x0001 // Incomplete RX Transmission - // Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCOUNT4 register. -// -//***************************************************************************** -#define USB_RXCOUNT4_COUNT_M 0x1FFF // Receive Packet Count -#define USB_RXCOUNT4_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXTYPE4 register. -// -//***************************************************************************** -#define USB_TXTYPE4_SPEED_M 0x00C0 // Operating Speed -#define USB_TXTYPE4_SPEED_DFLT 0x0000 // Default -#define USB_TXTYPE4_SPEED_HIGH 0x0040 // High -#define USB_TXTYPE4_SPEED_FULL 0x0080 // Full -#define USB_TXTYPE4_SPEED_LOW 0x00C0 // Low -#define USB_TXTYPE4_PROTO_M 0x0030 // Protocol -#define USB_TXTYPE4_PROTO_CTRL 0x0000 // Control -#define USB_TXTYPE4_PROTO_ISOC 0x0010 // Isochronous -#define USB_TXTYPE4_PROTO_BULK 0x0020 // Bulk -#define USB_TXTYPE4_PROTO_INT 0x0030 // Interrupt -#define USB_TXTYPE4_TEP_M 0x000F // Target Endpoint Number -#define USB_TXTYPE4_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXINTERVAL4 -// register. -// -//***************************************************************************** -#define USB_TXINTERVAL4_TXPOLL_M 0x00FF // TX Polling -#define USB_TXINTERVAL4_NAKLMT_M 0x00FF // NAK Limit -#define USB_TXINTERVAL4_NAKLMT_S 0 -#define USB_TXINTERVAL4_TXPOLL_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXTYPE4 register. -// -//***************************************************************************** -#define USB_RXTYPE4_SPEED_M 0x00C0 // Operating Speed -#define USB_RXTYPE4_SPEED_DFLT 0x0000 // Default -#define USB_RXTYPE4_SPEED_HIGH 0x0040 // High -#define USB_RXTYPE4_SPEED_FULL 0x0080 // Full -#define USB_RXTYPE4_SPEED_LOW 0x00C0 // Low -#define USB_RXTYPE4_PROTO_M 0x0030 // Protocol -#define USB_RXTYPE4_PROTO_CTRL 0x0000 // Control -#define USB_RXTYPE4_PROTO_ISOC 0x0010 // Isochronous -#define USB_RXTYPE4_PROTO_BULK 0x0020 // Bulk -#define USB_RXTYPE4_PROTO_INT 0x0030 // Interrupt -#define USB_RXTYPE4_TEP_M 0x000F // Target Endpoint Number -#define USB_RXTYPE4_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXINTERVAL4 -// register. -// -//***************************************************************************** -#define USB_RXINTERVAL4_TXPOLL_M 0x00FF // RX Polling -#define USB_RXINTERVAL4_NAKLMT_M 0x00FF // NAK Limit -#define USB_RXINTERVAL4_NAKLMT_S 0 -#define USB_RXINTERVAL4_TXPOLL_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXMAXP5 register. -// -//***************************************************************************** -#define USB_TXMAXP5_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_TXMAXP5_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRL5 register. -// -//***************************************************************************** -#define USB_TXCSRL5_NAKTO 0x0080 // NAK Timeout -#define USB_TXCSRL5_CLRDT 0x0040 // Clear Data Toggle -#define USB_TXCSRL5_STALLED 0x0020 // Endpoint Stalled -#define USB_TXCSRL5_SETUP 0x0010 // Setup Packet -#define USB_TXCSRL5_STALL 0x0010 // Send STALL -#define USB_TXCSRL5_FLUSH 0x0008 // Flush FIFO -#define USB_TXCSRL5_ERROR 0x0004 // Error -#define USB_TXCSRL5_UNDRN 0x0004 // Underrun -#define USB_TXCSRL5_FIFONE 0x0002 // FIFO Not Empty -#define USB_TXCSRL5_TXRDY 0x0001 // Transmit Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRH5 register. -// -//***************************************************************************** -#define USB_TXCSRH5_AUTOSET 0x0080 // Auto Set -#define USB_TXCSRH5_ISO 0x0040 // Isochronous Transfers -#define USB_TXCSRH5_MODE 0x0020 // Mode -#define USB_TXCSRH5_DMAEN 0x0010 // DMA Request Enable -#define USB_TXCSRH5_FDT 0x0008 // Force Data Toggle -#define USB_TXCSRH5_DMAMOD 0x0004 // DMA Request Mode -#define USB_TXCSRH5_DTWE 0x0002 // Data Toggle Write Enable -#define USB_TXCSRH5_DT 0x0001 // Data Toggle - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXMAXP5 register. -// -//***************************************************************************** -#define USB_RXMAXP5_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_RXMAXP5_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRL5 register. -// -//***************************************************************************** -#define USB_RXCSRL5_CLRDT 0x0080 // Clear Data Toggle -#define USB_RXCSRL5_STALLED 0x0040 // Endpoint Stalled -#define USB_RXCSRL5_STALL 0x0020 // Send STALL -#define USB_RXCSRL5_REQPKT 0x0020 // Request Packet -#define USB_RXCSRL5_FLUSH 0x0010 // Flush FIFO -#define USB_RXCSRL5_NAKTO 0x0008 // NAK Timeout -#define USB_RXCSRL5_DATAERR 0x0008 // Data Error -#define USB_RXCSRL5_ERROR 0x0004 // Error -#define USB_RXCSRL5_OVER 0x0004 // Overrun -#define USB_RXCSRL5_FULL 0x0002 // FIFO Full -#define USB_RXCSRL5_RXRDY 0x0001 // Receive Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRH5 register. -// -//***************************************************************************** -#define USB_RXCSRH5_AUTOCL 0x0080 // Auto Clear -#define USB_RXCSRH5_AUTORQ 0x0040 // Auto Request -#define USB_RXCSRH5_ISO 0x0040 // Isochronous Transfers -#define USB_RXCSRH5_DMAEN 0x0020 // DMA Request Enable -#define USB_RXCSRH5_DISNYET 0x0010 // Disable NYET -#define USB_RXCSRH5_PIDERR 0x0010 // PID Error -#define USB_RXCSRH5_DMAMOD 0x0008 // DMA Request Mode -#define USB_RXCSRH5_DTWE 0x0004 // Data Toggle Write Enable -#define USB_RXCSRH5_DT 0x0002 // Data Toggle -#define USB_RXCSRH5_INCOMPRX 0x0001 // Incomplete RX Transmission - // Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCOUNT5 register. +// The following are defines for the bit fields in the USB_O_DMACTL0 register. // //***************************************************************************** -#define USB_RXCOUNT5_COUNT_M 0x1FFF // Receive Packet Count -#define USB_RXCOUNT5_COUNT_S 0 +#define USB_DMACTL0_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL0_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL0_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL0_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified + // length +#define USB_DMACTL0_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or + // unspecified length +#define USB_DMACTL0_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL0_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL0_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL0_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL0_DIR 0x0002 // DMA Direction +#define USB_DMACTL0_ENABLE 0x0001 // DMA Transfer Enable +#define USB_DMACTL0_EP_S 4 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXTYPE5 register. +// The following are defines for the bit fields in the USB_O_DMAADDR0 register. // //***************************************************************************** -#define USB_TXTYPE5_SPEED_M 0x00C0 // Operating Speed -#define USB_TXTYPE5_SPEED_DFLT 0x0000 // Default -#define USB_TXTYPE5_SPEED_HIGH 0x0040 // High -#define USB_TXTYPE5_SPEED_FULL 0x0080 // Full -#define USB_TXTYPE5_SPEED_LOW 0x00C0 // Low -#define USB_TXTYPE5_PROTO_M 0x0030 // Protocol -#define USB_TXTYPE5_PROTO_CTRL 0x0000 // Control -#define USB_TXTYPE5_PROTO_ISOC 0x0010 // Isochronous -#define USB_TXTYPE5_PROTO_BULK 0x0020 // Bulk -#define USB_TXTYPE5_PROTO_INT 0x0030 // Interrupt -#define USB_TXTYPE5_TEP_M 0x000F // Target Endpoint Number -#define USB_TXTYPE5_TEP_S 0 +#define USB_DMAADDR0_ADDR_M 0xFFFFFFFC // DMA Address +#define USB_DMAADDR0_ADDR_S 2 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXINTERVAL5 +// The following are defines for the bit fields in the USB_O_DMACOUNT0 // register. // //***************************************************************************** -#define USB_TXINTERVAL5_TXPOLL_M 0x00FF // TX Polling -#define USB_TXINTERVAL5_NAKLMT_M 0x00FF // NAK Limit -#define USB_TXINTERVAL5_NAKLMT_S 0 -#define USB_TXINTERVAL5_TXPOLL_S 0 +#define USB_DMACOUNT0_COUNT_M 0xFFFFFFFC // DMA Count +#define USB_DMACOUNT0_COUNT_S 2 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXTYPE5 register. +// The following are defines for the bit fields in the USB_O_CTO register. // //***************************************************************************** -#define USB_RXTYPE5_SPEED_M 0x00C0 // Operating Speed -#define USB_RXTYPE5_SPEED_DFLT 0x0000 // Default -#define USB_RXTYPE5_SPEED_HIGH 0x0040 // High -#define USB_RXTYPE5_SPEED_FULL 0x0080 // Full -#define USB_RXTYPE5_SPEED_LOW 0x00C0 // Low -#define USB_RXTYPE5_PROTO_M 0x0030 // Protocol -#define USB_RXTYPE5_PROTO_CTRL 0x0000 // Control -#define USB_RXTYPE5_PROTO_ISOC 0x0010 // Isochronous -#define USB_RXTYPE5_PROTO_BULK 0x0020 // Bulk -#define USB_RXTYPE5_PROTO_INT 0x0030 // Interrupt -#define USB_RXTYPE5_TEP_M 0x000F // Target Endpoint Number -#define USB_RXTYPE5_TEP_S 0 +#define USB_CTO_CCTV_M 0xFFFF // Configurable Chirp Timeout Value +#define USB_CTO_CCTV_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXINTERVAL5 -// register. +// The following are defines for the bit fields in the USB_O_HHSRTN register. // //***************************************************************************** -#define USB_RXINTERVAL5_TXPOLL_M 0x00FF // RX Polling -#define USB_RXINTERVAL5_NAKLMT_M 0x00FF // NAK Limit -#define USB_RXINTERVAL5_TXPOLL_S 0 -#define USB_RXINTERVAL5_NAKLMT_S 0 +#define USB_HHSRTN_HHSRTN_M 0xFFFF // HIgh Speed to UTM Operating + // Delay +#define USB_HHSRTN_HHSRTN_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXMAXP6 register. -// -//***************************************************************************** -#define USB_TXMAXP6_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_TXMAXP6_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRL6 register. -// -//***************************************************************************** -#define USB_TXCSRL6_NAKTO 0x0080 // NAK Timeout -#define USB_TXCSRL6_CLRDT 0x0040 // Clear Data Toggle -#define USB_TXCSRL6_STALLED 0x0020 // Endpoint Stalled -#define USB_TXCSRL6_STALL 0x0010 // Send STALL -#define USB_TXCSRL6_SETUP 0x0010 // Setup Packet -#define USB_TXCSRL6_FLUSH 0x0008 // Flush FIFO -#define USB_TXCSRL6_ERROR 0x0004 // Error -#define USB_TXCSRL6_UNDRN 0x0004 // Underrun -#define USB_TXCSRL6_FIFONE 0x0002 // FIFO Not Empty -#define USB_TXCSRL6_TXRDY 0x0001 // Transmit Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRH6 register. -// -//***************************************************************************** -#define USB_TXCSRH6_AUTOSET 0x0080 // Auto Set -#define USB_TXCSRH6_ISO 0x0040 // Isochronous Transfers -#define USB_TXCSRH6_MODE 0x0020 // Mode -#define USB_TXCSRH6_DMAEN 0x0010 // DMA Request Enable -#define USB_TXCSRH6_FDT 0x0008 // Force Data Toggle -#define USB_TXCSRH6_DMAMOD 0x0004 // DMA Request Mode -#define USB_TXCSRH6_DTWE 0x0002 // Data Toggle Write Enable -#define USB_TXCSRH6_DT 0x0001 // Data Toggle - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXMAXP6 register. -// -//***************************************************************************** -#define USB_RXMAXP6_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_RXMAXP6_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRL6 register. -// -//***************************************************************************** -#define USB_RXCSRL6_CLRDT 0x0080 // Clear Data Toggle -#define USB_RXCSRL6_STALLED 0x0040 // Endpoint Stalled -#define USB_RXCSRL6_REQPKT 0x0020 // Request Packet -#define USB_RXCSRL6_STALL 0x0020 // Send STALL -#define USB_RXCSRL6_FLUSH 0x0010 // Flush FIFO -#define USB_RXCSRL6_NAKTO 0x0008 // NAK Timeout -#define USB_RXCSRL6_DATAERR 0x0008 // Data Error -#define USB_RXCSRL6_ERROR 0x0004 // Error -#define USB_RXCSRL6_OVER 0x0004 // Overrun -#define USB_RXCSRL6_FULL 0x0002 // FIFO Full -#define USB_RXCSRL6_RXRDY 0x0001 // Receive Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRH6 register. -// -//***************************************************************************** -#define USB_RXCSRH6_AUTOCL 0x0080 // Auto Clear -#define USB_RXCSRH6_AUTORQ 0x0040 // Auto Request -#define USB_RXCSRH6_ISO 0x0040 // Isochronous Transfers -#define USB_RXCSRH6_DMAEN 0x0020 // DMA Request Enable -#define USB_RXCSRH6_DISNYET 0x0010 // Disable NYET -#define USB_RXCSRH6_PIDERR 0x0010 // PID Error -#define USB_RXCSRH6_DMAMOD 0x0008 // DMA Request Mode -#define USB_RXCSRH6_DTWE 0x0004 // Data Toggle Write Enable -#define USB_RXCSRH6_DT 0x0002 // Data Toggle -#define USB_RXCSRH6_INCOMPRX 0x0001 // Incomplete RX Transmission - // Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCOUNT6 register. -// -//***************************************************************************** -#define USB_RXCOUNT6_COUNT_M 0x1FFF // Receive Packet Count -#define USB_RXCOUNT6_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXTYPE6 register. -// -//***************************************************************************** -#define USB_TXTYPE6_SPEED_M 0x00C0 // Operating Speed -#define USB_TXTYPE6_SPEED_DFLT 0x0000 // Default -#define USB_TXTYPE6_SPEED_HIGH 0x0040 // High -#define USB_TXTYPE6_SPEED_FULL 0x0080 // Full -#define USB_TXTYPE6_SPEED_LOW 0x00C0 // Low -#define USB_TXTYPE6_PROTO_M 0x0030 // Protocol -#define USB_TXTYPE6_PROTO_CTRL 0x0000 // Control -#define USB_TXTYPE6_PROTO_ISOC 0x0010 // Isochronous -#define USB_TXTYPE6_PROTO_BULK 0x0020 // Bulk -#define USB_TXTYPE6_PROTO_INT 0x0030 // Interrupt -#define USB_TXTYPE6_TEP_M 0x000F // Target Endpoint Number -#define USB_TXTYPE6_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXINTERVAL6 -// register. -// -//***************************************************************************** -#define USB_TXINTERVAL6_TXPOLL_M 0x00FF // TX Polling -#define USB_TXINTERVAL6_NAKLMT_M 0x00FF // NAK Limit -#define USB_TXINTERVAL6_TXPOLL_S 0 -#define USB_TXINTERVAL6_NAKLMT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXTYPE6 register. -// -//***************************************************************************** -#define USB_RXTYPE6_SPEED_M 0x00C0 // Operating Speed -#define USB_RXTYPE6_SPEED_DFLT 0x0000 // Default -#define USB_RXTYPE6_SPEED_HIGH 0x0040 // High -#define USB_RXTYPE6_SPEED_FULL 0x0080 // Full -#define USB_RXTYPE6_SPEED_LOW 0x00C0 // Low -#define USB_RXTYPE6_PROTO_M 0x0030 // Protocol -#define USB_RXTYPE6_PROTO_CTRL 0x0000 // Control -#define USB_RXTYPE6_PROTO_ISOC 0x0010 // Isochronous -#define USB_RXTYPE6_PROTO_BULK 0x0020 // Bulk -#define USB_RXTYPE6_PROTO_INT 0x0030 // Interrupt -#define USB_RXTYPE6_TEP_M 0x000F // Target Endpoint Number -#define USB_RXTYPE6_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXINTERVAL6 -// register. -// -//***************************************************************************** -#define USB_RXINTERVAL6_TXPOLL_M 0x00FF // RX Polling -#define USB_RXINTERVAL6_NAKLMT_M 0x00FF // NAK Limit -#define USB_RXINTERVAL6_NAKLMT_S 0 -#define USB_RXINTERVAL6_TXPOLL_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXMAXP7 register. -// -//***************************************************************************** -#define USB_TXMAXP7_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_TXMAXP7_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRL7 register. -// -//***************************************************************************** -#define USB_TXCSRL7_NAKTO 0x0080 // NAK Timeout -#define USB_TXCSRL7_CLRDT 0x0040 // Clear Data Toggle -#define USB_TXCSRL7_STALLED 0x0020 // Endpoint Stalled -#define USB_TXCSRL7_STALL 0x0010 // Send STALL -#define USB_TXCSRL7_SETUP 0x0010 // Setup Packet -#define USB_TXCSRL7_FLUSH 0x0008 // Flush FIFO -#define USB_TXCSRL7_ERROR 0x0004 // Error -#define USB_TXCSRL7_UNDRN 0x0004 // Underrun -#define USB_TXCSRL7_FIFONE 0x0002 // FIFO Not Empty -#define USB_TXCSRL7_TXRDY 0x0001 // Transmit Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRH7 register. -// -//***************************************************************************** -#define USB_TXCSRH7_AUTOSET 0x0080 // Auto Set -#define USB_TXCSRH7_ISO 0x0040 // Isochronous Transfers -#define USB_TXCSRH7_MODE 0x0020 // Mode -#define USB_TXCSRH7_DMAEN 0x0010 // DMA Request Enable -#define USB_TXCSRH7_FDT 0x0008 // Force Data Toggle -#define USB_TXCSRH7_DMAMOD 0x0004 // DMA Request Mode -#define USB_TXCSRH7_DTWE 0x0002 // Data Toggle Write Enable -#define USB_TXCSRH7_DT 0x0001 // Data Toggle - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXMAXP7 register. -// -//***************************************************************************** -#define USB_RXMAXP7_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_RXMAXP7_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRL7 register. -// -//***************************************************************************** -#define USB_RXCSRL7_CLRDT 0x0080 // Clear Data Toggle -#define USB_RXCSRL7_STALLED 0x0040 // Endpoint Stalled -#define USB_RXCSRL7_REQPKT 0x0020 // Request Packet -#define USB_RXCSRL7_STALL 0x0020 // Send STALL -#define USB_RXCSRL7_FLUSH 0x0010 // Flush FIFO -#define USB_RXCSRL7_DATAERR 0x0008 // Data Error -#define USB_RXCSRL7_NAKTO 0x0008 // NAK Timeout -#define USB_RXCSRL7_ERROR 0x0004 // Error -#define USB_RXCSRL7_OVER 0x0004 // Overrun -#define USB_RXCSRL7_FULL 0x0002 // FIFO Full -#define USB_RXCSRL7_RXRDY 0x0001 // Receive Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRH7 register. -// -//***************************************************************************** -#define USB_RXCSRH7_AUTOCL 0x0080 // Auto Clear -#define USB_RXCSRH7_ISO 0x0040 // Isochronous Transfers -#define USB_RXCSRH7_AUTORQ 0x0040 // Auto Request -#define USB_RXCSRH7_DMAEN 0x0020 // DMA Request Enable -#define USB_RXCSRH7_PIDERR 0x0010 // PID Error -#define USB_RXCSRH7_DISNYET 0x0010 // Disable NYET -#define USB_RXCSRH7_DMAMOD 0x0008 // DMA Request Mode -#define USB_RXCSRH7_DTWE 0x0004 // Data Toggle Write Enable -#define USB_RXCSRH7_DT 0x0002 // Data Toggle -#define USB_RXCSRH7_INCOMPRX 0x0001 // Incomplete RX Transmission - // Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCOUNT7 register. -// -//***************************************************************************** -#define USB_RXCOUNT7_COUNT_M 0x1FFF // Receive Packet Count -#define USB_RXCOUNT7_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXTYPE7 register. -// -//***************************************************************************** -#define USB_TXTYPE7_SPEED_M 0x00C0 // Operating Speed -#define USB_TXTYPE7_SPEED_DFLT 0x0000 // Default -#define USB_TXTYPE7_SPEED_HIGH 0x0040 // High -#define USB_TXTYPE7_SPEED_FULL 0x0080 // Full -#define USB_TXTYPE7_SPEED_LOW 0x00C0 // Low -#define USB_TXTYPE7_PROTO_M 0x0030 // Protocol -#define USB_TXTYPE7_PROTO_CTRL 0x0000 // Control -#define USB_TXTYPE7_PROTO_ISOC 0x0010 // Isochronous -#define USB_TXTYPE7_PROTO_BULK 0x0020 // Bulk -#define USB_TXTYPE7_PROTO_INT 0x0030 // Interrupt -#define USB_TXTYPE7_TEP_M 0x000F // Target Endpoint Number -#define USB_TXTYPE7_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXINTERVAL7 -// register. -// -//***************************************************************************** -#define USB_TXINTERVAL7_TXPOLL_M 0x00FF // TX Polling -#define USB_TXINTERVAL7_NAKLMT_M 0x00FF // NAK Limit -#define USB_TXINTERVAL7_NAKLMT_S 0 -#define USB_TXINTERVAL7_TXPOLL_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXTYPE7 register. -// -//***************************************************************************** -#define USB_RXTYPE7_SPEED_M 0x00C0 // Operating Speed -#define USB_RXTYPE7_SPEED_DFLT 0x0000 // Default -#define USB_RXTYPE7_SPEED_HIGH 0x0040 // High -#define USB_RXTYPE7_SPEED_FULL 0x0080 // Full -#define USB_RXTYPE7_SPEED_LOW 0x00C0 // Low -#define USB_RXTYPE7_PROTO_M 0x0030 // Protocol -#define USB_RXTYPE7_PROTO_CTRL 0x0000 // Control -#define USB_RXTYPE7_PROTO_ISOC 0x0010 // Isochronous -#define USB_RXTYPE7_PROTO_BULK 0x0020 // Bulk -#define USB_RXTYPE7_PROTO_INT 0x0030 // Interrupt -#define USB_RXTYPE7_TEP_M 0x000F // Target Endpoint Number -#define USB_RXTYPE7_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXINTERVAL7 -// register. -// -//***************************************************************************** -#define USB_RXINTERVAL7_TXPOLL_M 0x00FF // RX Polling -#define USB_RXINTERVAL7_NAKLMT_M 0x00FF // NAK Limit -#define USB_RXINTERVAL7_NAKLMT_S 0 -#define USB_RXINTERVAL7_TXPOLL_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAINTR register. -// -//***************************************************************************** -#define USB_DMAINTR_CH7 0x0080 // Channel 7 DMA Interrupt -#define USB_DMAINTR_CH6 0x0040 // Channel 6 DMA Interrupt -#define USB_DMAINTR_CH5 0x0020 // Channel 5 DMA Interrupt -#define USB_DMAINTR_CH4 0x0010 // Channel 4 DMA Interrupt -#define USB_DMAINTR_CH3 0x0008 // Channel 3 DMA Interrupt -#define USB_DMAINTR_CH2 0x0004 // Channel 2 DMA Interrupt -#define USB_DMAINTR_CH1 0x0002 // Channel 1 DMA Interrupt -#define USB_DMAINTR_CH0 0x0001 // Channel 0 DMA Interrupt - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL0 register. -// -//***************************************************************************** -#define USB_DMACTL0_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL0_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL0_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL0_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL0_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL0_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL0_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL0_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL0_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL0_DIR 0x0002 // DMA Direction -#define USB_DMACTL0_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL0_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR0 register. -// -//***************************************************************************** -#define USB_DMAADDR0_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR0_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT0 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT0_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT0_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL1 register. -// -//***************************************************************************** -#define USB_DMACTL1_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL1_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL1_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL1_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL1_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL1_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL1_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL1_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL1_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL1_DIR 0x0002 // DMA Direction -#define USB_DMACTL1_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL1_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR1 register. -// -//***************************************************************************** -#define USB_DMAADDR1_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR1_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT1 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT1_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT1_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL2 register. -// -//***************************************************************************** -#define USB_DMACTL2_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL2_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL2_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL2_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL2_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL2_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL2_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL2_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL2_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL2_DIR 0x0002 // DMA Direction -#define USB_DMACTL2_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL2_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR2 register. -// -//***************************************************************************** -#define USB_DMAADDR2_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR2_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT2 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT2_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT2_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL3 register. -// -//***************************************************************************** -#define USB_DMACTL3_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL3_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL3_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL3_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL3_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL3_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL3_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL3_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL3_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL3_DIR 0x0002 // DMA Direction -#define USB_DMACTL3_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL3_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR3 register. -// -//***************************************************************************** -#define USB_DMAADDR3_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR3_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT3 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT3_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT3_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL4 register. -// -//***************************************************************************** -#define USB_DMACTL4_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL4_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL4_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL4_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL4_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL4_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL4_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL4_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL4_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL4_DIR 0x0002 // DMA Direction -#define USB_DMACTL4_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL4_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR4 register. -// -//***************************************************************************** -#define USB_DMAADDR4_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR4_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT4 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT4_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT4_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL5 register. -// -//***************************************************************************** -#define USB_DMACTL5_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL5_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL5_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL5_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL5_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL5_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL5_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL5_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL5_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL5_DIR 0x0002 // DMA Direction -#define USB_DMACTL5_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL5_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR5 register. -// -//***************************************************************************** -#define USB_DMAADDR5_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR5_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT5 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT5_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT5_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL6 register. -// -//***************************************************************************** -#define USB_DMACTL6_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL6_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL6_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL6_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL6_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL6_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL6_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL6_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL6_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL6_DIR 0x0002 // DMA Direction -#define USB_DMACTL6_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL6_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR6 register. -// -//***************************************************************************** -#define USB_DMAADDR6_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR6_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT6 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT6_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT6_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL7 register. -// -//***************************************************************************** -#define USB_DMACTL7_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL7_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL7_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL7_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL7_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL7_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL7_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL7_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL7_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL7_DIR 0x0002 // DMA Direction -#define USB_DMACTL7_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL7_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR7 register. -// -//***************************************************************************** -#define USB_DMAADDR7_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR7_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT7 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT7_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT7_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RQPKTCOUNT1 -// register. -// -//***************************************************************************** -#define USB_RQPKTCOUNT1_M 0xFFFF // Block Transfer Packet Count -#define USB_RQPKTCOUNT1_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RQPKTCOUNT2 -// register. -// -//***************************************************************************** -#define USB_RQPKTCOUNT2_M 0xFFFF // Block Transfer Packet Count -#define USB_RQPKTCOUNT2_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RQPKTCOUNT3 -// register. -// -//***************************************************************************** -#define USB_RQPKTCOUNT3_M 0xFFFF // Block Transfer Packet Count -#define USB_RQPKTCOUNT3_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RQPKTCOUNT4 -// register. -// -//***************************************************************************** -#define USB_RQPKTCOUNT4_COUNT_M 0xFFFF // Block Transfer Packet Count -#define USB_RQPKTCOUNT4_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RQPKTCOUNT5 -// register. -// -//***************************************************************************** -#define USB_RQPKTCOUNT5_COUNT_M 0xFFFF // Block Transfer Packet Count -#define USB_RQPKTCOUNT5_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RQPKTCOUNT6 -// register. -// -//***************************************************************************** -#define USB_RQPKTCOUNT6_COUNT_M 0xFFFF // Block Transfer Packet Count -#define USB_RQPKTCOUNT6_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RQPKTCOUNT7 -// register. -// -//***************************************************************************** -#define USB_RQPKTCOUNT7_COUNT_M 0xFFFF // Block Transfer Packet Count -#define USB_RQPKTCOUNT7_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXDPKTBUFDIS -// register. -// -//***************************************************************************** -#define USB_RXDPKTBUFDIS_EP7 0x0080 // EP7 RX Double-Packet Buffer - // Disable -#define USB_RXDPKTBUFDIS_EP6 0x0040 // EP6 RX Double-Packet Buffer - // Disable -#define USB_RXDPKTBUFDIS_EP5 0x0020 // EP5 RX Double-Packet Buffer - // Disable -#define USB_RXDPKTBUFDIS_EP4 0x0010 // EP4 RX Double-Packet Buffer - // Disable -#define USB_RXDPKTBUFDIS_EP3 0x0008 // EP3 RX Double-Packet Buffer - // Disable -#define USB_RXDPKTBUFDIS_EP2 0x0004 // EP2 RX Double-Packet Buffer - // Disable -#define USB_RXDPKTBUFDIS_EP1 0x0002 // EP1 RX Double-Packet Buffer - // Disable - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXDPKTBUFDIS -// register. -// -//***************************************************************************** -#define USB_TXDPKTBUFDIS_EP7 0x0080 // EP7 TX Double-Packet Buffer - // Disable -#define USB_TXDPKTBUFDIS_EP6 0x0040 // EP6 TX Double-Packet Buffer - // Disable -#define USB_TXDPKTBUFDIS_EP5 0x0020 // EP5 TX Double-Packet Buffer - // Disable -#define USB_TXDPKTBUFDIS_EP4 0x0010 // EP4 TX Double-Packet Buffer - // Disable -#define USB_TXDPKTBUFDIS_EP3 0x0008 // EP3 TX Double-Packet Buffer - // Disable -#define USB_TXDPKTBUFDIS_EP2 0x0004 // EP2 TX Double-Packet Buffer - // Disable -#define USB_TXDPKTBUFDIS_EP1 0x0002 // EP1 TX Double-Packet Buffer - // Disable - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_CTO register. -// -//***************************************************************************** -#define USB_CTO_CCTV_M 0xFFFF // Configurable Chirp Timeout Value -#define USB_CTO_CCTV_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_HHSRTN register. -// -//***************************************************************************** -#define USB_HHSRTN_HHSRTN_M 0xFFFF // HIgh Speed to UTM Operating - // Delay -#define USB_HHSRTN_HHSRTN_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_HSBT register. +// The following are defines for the bit fields in the USB_O_HSBT register. // //***************************************************************************** #define USB_HSBT_HSBT_M 0x000F // High Speed Timeout Adder #define USB_HSBT_HSBT_S 0 -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_LPMATTR register. -// -//***************************************************************************** -#define USB_LPMATTR_ENDPT_M 0xF000 // Endpoint -#define USB_LPMATTR_RMTWAK 0x0100 // Remote Wake -#define USB_LPMATTR_HIRD_M 0x00F0 // Host Initiated Resume Duration -#define USB_LPMATTR_LS_M 0x000F // Link State -#define USB_LPMATTR_LS_L1 0x0001 // Sleep State (L1) -#define USB_LPMATTR_ENDPT_S 12 -#define USB_LPMATTR_HIRD_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_LPMCNTRL register. -// -//***************************************************************************** -#define USB_LPMCNTRL_NAK 0x0010 // LPM NAK -#define USB_LPMCNTRL_EN_M 0x000C // LPM Enable -#define USB_LPMCNTRL_EN_NONE 0x0000 // LPM and Extended transactions - // are not supported. In this case, - // the USB does not respond to LPM - // transactions and LPM - // transactions cause a timeout -#define USB_LPMCNTRL_EN_EXT 0x0004 // LPM is not supported but - // extended transactions are - // supported. In this case, the USB - // does respond to an LPM - // transaction with a STALL -#define USB_LPMCNTRL_EN_LPMEXT 0x000C // The USB supports LPM extended - // transactions. In this case, the - // USB responds with a NYET or an - // ACK as determined by the value - // of TXLPM and other conditions -#define USB_LPMCNTRL_RES 0x0002 // LPM Resume -#define USB_LPMCNTRL_TXLPM 0x0001 // Transmit LPM Transaction Enable - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_LPMIM register. -// -//***************************************************************************** -#define USB_LPMIM_ERR 0x0020 // LPM Error Interrupt Mask -#define USB_LPMIM_RES 0x0010 // LPM Resume Interrupt Mask -#define USB_LPMIM_NC 0x0008 // LPM NC Interrupt Mask -#define USB_LPMIM_ACK 0x0004 // LPM ACK Interrupt Mask -#define USB_LPMIM_NY 0x0002 // LPM NY Interrupt Mask -#define USB_LPMIM_STALL 0x0001 // LPM STALL Interrupt Mask - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_LPMRIS register. -// -//***************************************************************************** -#define USB_LPMRIS_ERR 0x0020 // LPM Interrupt Status -#define USB_LPMRIS_RES 0x0010 // LPM Resume Interrupt Status -#define USB_LPMRIS_NC 0x0008 // LPM NC Interrupt Status -#define USB_LPMRIS_ACK 0x0004 // LPM ACK Interrupt Status -#define USB_LPMRIS_NY 0x0002 // LPM NY Interrupt Status -#define USB_LPMRIS_LPMST 0x0001 // LPM STALL Interrupt Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_LPMFADDR register. -// -//***************************************************************************** -#define USB_LPMFADDR_ADDR_M 0x007F // LPM Function Address -#define USB_LPMFADDR_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_EPC register. -// -//***************************************************************************** -#define USB_EPC_PFLTACT_M 0x0300 // Power Fault Action -#define USB_EPC_PFLTACT_UNCHG 0x0000 // Unchanged -#define USB_EPC_PFLTACT_TRIS 0x0100 // Tristate -#define USB_EPC_PFLTACT_LOW 0x0200 // Low -#define USB_EPC_PFLTACT_HIGH 0x0300 // High -#define USB_EPC_PFLTAEN 0x0040 // Power Fault Action Enable -#define USB_EPC_PFLTSEN_HIGH 0x0020 // Power Fault Sense -#define USB_EPC_PFLTEN 0x0010 // Power Fault Input Enable -#define USB_EPC_EPENDE 0x0004 // EPEN Drive Enable -#define USB_EPC_EPEN_M 0x0003 // External Power Supply Enable - // Configuration -#define USB_EPC_EPEN_LOW 0x0000 // Power Enable Active Low -#define USB_EPC_EPEN_HIGH 0x0001 // Power Enable Active High -#define USB_EPC_EPEN_VBLOW 0x0002 // Power Enable High if VBUS Low - // (OTG only) -#define USB_EPC_EPEN_VBHIGH 0x0003 // Power Enable High if VBUS High - // (OTG only) - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_EPCRIS register. -// -//***************************************************************************** -#define USB_EPCRIS_PF 0x0001 // USB Power Fault Interrupt Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_EPCIM register. -// -//***************************************************************************** -#define USB_EPCIM_PF 0x0001 // USB Power Fault Interrupt Mask - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_EPCISC register. -// -//***************************************************************************** -#define USB_EPCISC_PF 0x0001 // USB Power Fault Interrupt Status - // and Clear - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DRRIS register. -// -//***************************************************************************** -#define USB_DRRIS_RESUME 0x0001 // RESUME Interrupt Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DRIM register. -// -//***************************************************************************** -#define USB_DRIM_RESUME 0x0001 // RESUME Interrupt Mask - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DRISC register. -// -//***************************************************************************** -#define USB_DRISC_RESUME 0x0001 // RESUME Interrupt Status and - // Clear - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_GPCS register. -// -//***************************************************************************** -#define USB_GPCS_DEVMOD_M 0x0007 // Device Mode -#define USB_GPCS_DEVMOD_OTG 0x0000 // Use USB0VBUS and USB0ID pin -#define USB_GPCS_DEVMOD_HOST 0x0002 // Force USB0VBUS and USB0ID low -#define USB_GPCS_DEVMOD_DEV 0x0003 // Force USB0VBUS and USB0ID high -#define USB_GPCS_DEVMOD_HOSTVBUS \ - 0x0004 // Use USB0VBUS and force USB0ID - // low -#define USB_GPCS_DEVMOD_DEVVBUS 0x0005 // Use USB0VBUS and force USB0ID - // high - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_VDC register. -// -//***************************************************************************** -#define USB_VDC_VBDEN 0x0001 // VBUS Droop Enable - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_VDCRIS register. -// -//***************************************************************************** -#define USB_VDCRIS_VD 0x0001 // VBUS Droop Raw Interrupt Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_VDCIM register. -// -//***************************************************************************** -#define USB_VDCIM_VD 0x0001 // VBUS Droop Interrupt Mask - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_VDCISC register. -// -//***************************************************************************** -#define USB_VDCISC_VD 0x0001 // VBUS Droop Interrupt Status and - // Clear - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_PP register. -// -//***************************************************************************** -#define USB_PP_ECNT_M 0xFF00 // Endpoint Count -#define USB_PP_USB_M 0x00C0 // USB Capability -#define USB_PP_USB_DEVICE 0x0040 // DEVICE -#define USB_PP_USB_HOSTDEVICE 0x0080 // HOST -#define USB_PP_USB_OTG 0x00C0 // OTG -#define USB_PP_ULPI 0x0020 // ULPI Present -#define USB_PP_PHY 0x0010 // PHY Present -#define USB_PP_TYPE_M 0x000F // Controller Type -#define USB_PP_TYPE_0 0x0000 // The first-generation USB - // controller -#define USB_PP_TYPE_1 0x0001 // The second-generation USB - // controller revision -#define USB_PP_ECNT_S 8 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_PC register. -// -//***************************************************************************** -#define USB_PC_ULPIEN 0x00010000 // ULPI Enable - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_CC register. -// -//***************************************************************************** -#define USB_CC_CLKEN 0x0200 // USB Clock Enable -#define USB_CC_CSD 0x0100 // Clock Source/Direction -#define USB_CC_CLKDIV_M 0x000F // PLL Clock Divisor -#define USB_CC_CLKDIV_S 0 - #ifdef __cplusplus } #endif -- cgit v1.3.1 From fe7ffc8edaad069955d6ededb3fc77084338256c Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 17 Aug 2024 19:08:48 +0700 Subject: rename register bit definition to prevent conflict --- src/portable/mentor/musb/dcd_musb.c | 98 +++---- src/portable/mentor/musb/musb_type.h | 518 +++++++++++++++++------------------ 2 files changed, 308 insertions(+), 308 deletions(-) diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 3dcb9cdf1..3fd4d953a 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -240,7 +240,7 @@ static void process_setup_packet(uint8_t rhport) { /* Clear RX FIFO and reverse the transaction direction */ if (len && dir_in) { musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0); - ep_csr->csr0l = USB_CSRL0_RXRDYC; + ep_csr->csr0l = MUSB_CSRL0_RXRDYC; } } @@ -272,7 +272,7 @@ static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) } pipe->remaining = rem - len; } - ep_csr->tx_csrl = USB_TXCSRL1_TXRDY; + ep_csr->tx_csrl = MUSB_TXCSRL1_TXRDY; // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum, ep_csr->tx_csrl, rem - len); return false; } @@ -286,7 +286,7 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, ep_csr->rx_csrl); - TU_ASSERT(ep_csr->rx_csrl & USB_RXCSRL1_RXRDY); + TU_ASSERT(ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY); const unsigned mps = ep_csr->rx_maxp; const unsigned rem = pipe->remaining; @@ -327,7 +327,7 @@ static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16 } else { musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); - if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) ep_csr->rx_csrl = 0; + if (ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY) ep_csr->rx_csrl = 0; } return true; } @@ -377,9 +377,9 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ _dcd.status_out = 1; /* Flush TX FIFO and reverse the transaction direction. */ - ep_csr->csr0l = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND; + ep_csr->csr0l = MUSB_CSRL0_TXRDY | MUSB_CSRL0_DATAEND; } else { - ep_csr->csr0l = USB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ + ep_csr->csr0l = MUSB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ } // TU_LOG1(" IN ep_csr->csr0l = %x\r\n", ep_csr->csr0l); } else { @@ -387,7 +387,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ _dcd.pipe0.buf = buffer; _dcd.pipe0.length = len; _dcd.pipe0.remaining = len; - ep_csr->csr0l = USB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ + ep_csr->csr0l = MUSB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ } } else if (dir_in) { // TU_LOG1(" STATUS IN ep_csr->csr0l = %x\r\n", ep_csr->csr0l); @@ -395,7 +395,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO and reverse the transaction direction */ - ep_csr->csr0l = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; + ep_csr->csr0l = MUSB_CSRL0_RXRDYC | MUSB_CSRL0_DATAEND; } return true; } @@ -409,16 +409,16 @@ static void process_ep0(uint8_t rhport) // TU_LOG1(" EP0 ep_csr->csr0l = %x\r\n", csrl); // 21.1.5: endpoint 0 service routine as peripheral - if (csrl & USB_CSRL0_STALLED) { + if (csrl & MUSB_CSRL0_STALLED) { /* Returned STALL packet to HOST. */ ep_csr->csr0l = 0; /* Clear STALL */ return; } unsigned req = _dcd.setup_packet.bmRequestType; - if (csrl & USB_CSRL0_SETEND) { + if (csrl & MUSB_CSRL0_SETEND) { TU_LOG1(" ABORT by the next packets\r\n"); - ep_csr->csr0l = USB_CSRL0_SETENDC; + ep_csr->csr0l = MUSB_CSRL0_SETENDC; if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { /* DATA stage was aborted by receiving STATUS or SETUP packet. */ _dcd.pipe0.buf = NULL; @@ -429,10 +429,10 @@ static void process_ep0(uint8_t rhport) XFER_RESULT_SUCCESS, true); } req = REQUEST_TYPE_INVALID; - if (!(csrl & USB_CSRL0_RXRDY)) return; /* Received SETUP packet */ + if (!(csrl & MUSB_CSRL0_RXRDY)) return; /* Received SETUP packet */ } - if (csrl & USB_CSRL0_RXRDY) { + if (csrl & MUSB_CSRL0_RXRDY) { /* Received SETUP or DATA OUT packet */ if (req == REQUEST_TYPE_INVALID) { /* SETUP */ @@ -496,15 +496,15 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); if (dir_in) { // TU_LOG1(" TX CSRL%d = %x\r\n", epn, ep_csr->tx_csrl); - if (ep_csr->tx_csrl & USB_TXCSRL1_STALLED) { - ep_csr->tx_csrl &= ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_UNDRN); + if (ep_csr->tx_csrl & MUSB_TXCSRL1_STALLED) { + ep_csr->tx_csrl &= ~(MUSB_TXCSRL1_STALLED | MUSB_TXCSRL1_UNDRN); return; } completed = handle_xfer_in(rhport, ep_addr); } else { // TU_LOG1(" RX CSRL%d = %x\r\n", epn, ep_csr->rx_csrl); - if (ep_csr->rx_csrl & USB_RXCSRL1_STALLED) { - ep_csr->rx_csrl &= ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_OVER); + if (ep_csr->rx_csrl & MUSB_RXCSRL1_STALLED) { + ep_csr->rx_csrl &= ~(MUSB_RXCSRL1_STALLED | MUSB_RXCSRL1_OVER); return; } completed = handle_xfer_out(rhport, ep_addr); @@ -541,7 +541,7 @@ static void process_bus_reset(uint8_t rhport) { fifo_reset(musb, i, 0); fifo_reset(musb, i, 1); } - dcd_event_bus_reset(rhport, (musb->power & USB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); + dcd_event_bus_reset(rhport, (musb->power & MUSB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); } /*------------------------------------------------------------------ @@ -576,7 +576,7 @@ void dcd_init(uint8_t rhport) { print_musb_info(musb_regs); #endif - musb_regs->intr_usben |= USB_IE_SUSPND; + musb_regs->intr_usben |= MUSB_IE_SUSPND; musb_dcd_int_clear(rhport); musb_dcd_phy_init(rhport); dcd_connect(rhport); @@ -601,33 +601,33 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO to return ACK. */ - ep_csr->csr0l = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; + ep_csr->csr0l = MUSB_CSRL0_RXRDYC | MUSB_CSRL0_DATAEND; } // Wake up host void dcd_remote_wakeup(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); - musb_regs->power |= USB_POWER_RESUME; + musb_regs->power |= MUSB_POWER_RESUME; unsigned cnt = SystemCoreClock / 1000; while (cnt--) __NOP(); - musb_regs->power &= ~USB_POWER_RESUME; + musb_regs->power &= ~MUSB_POWER_RESUME; } // Connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); - musb_regs->power |= TUD_OPT_HIGH_SPEED ? USB_POWER_HSENAB : 0; - musb_regs->power |= USB_POWER_SOFTCONN; + musb_regs->power |= TUD_OPT_HIGH_SPEED ? MUSB_POWER_HSENAB : 0; + musb_regs->power |= MUSB_POWER_SOFTCONN; } // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); - musb_regs->power &= ~USB_POWER_SOFTCONN; + musb_regs->power &= ~MUSB_POWER_SOFTCONN; } void dcd_sof_enable(uint8_t rhport, bool en) @@ -663,7 +663,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) const uint8_t is_rx = 1 - dir_in; ep_csr->maxp_csr[is_rx].maxp = mps; - ep_csr->maxp_csr[is_rx].csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; + ep_csr->maxp_csr[is_rx].csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? MUSB_RXCSRH1_ISO : 0; uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx); if (ep_csr->maxp_csr[is_rx].csrl & MUSB_CSRL_PACKET_READY(is_rx)) { @@ -690,17 +690,17 @@ void dcd_edpt_close_all(uint8_t rhport) musb_ep_csr_t* ep_csr = get_ep_csr(musb, i); ep_csr->tx_maxp = 0; ep_csr->tx_csrh = 0; - if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) - ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + if (ep_csr->tx_csrl & MUSB_TXCSRL1_TXRDY) + ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT | MUSB_TXCSRL1_FLUSH; else - ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; + ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT; ep_csr->rx_maxp = 0; ep_csr->rx_csrh = 0; - if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) { - ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + if (ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY) { + ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT | MUSB_RXCSRL1_FLUSH; } else { - ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; + ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT; } fifo_reset(musb, i, 0); @@ -727,19 +727,19 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) musb->intr_txen &= ~TU_BIT(epn); ep_csr->tx_maxp = 0; ep_csr->tx_csrh = 0; - if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) { - ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + if (ep_csr->tx_csrl & MUSB_TXCSRL1_TXRDY) { + ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT | MUSB_TXCSRL1_FLUSH; } else { - ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; + ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT; } } else { musb->intr_rxen &= ~TU_BIT(epn); ep_csr->rx_maxp = 0; ep_csr->rx_csrh = 0; - if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) { - ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + if (ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY) { + ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT | MUSB_RXCSRL1_FLUSH; } else { - ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; + ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT; } } fifo_reset(musb, epn, dir_in); @@ -792,14 +792,14 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { if (!ep_addr) { /* Ignore EP80 */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.pipe0.buf = NULL; - ep_csr->csr0l = USB_CSRL0_STALL; + ep_csr->csr0l = MUSB_CSRL0_STALL; } } else { if (tu_edpt_dir(ep_addr)) { /* IN */ - ep_csr->tx_csrl = USB_TXCSRL1_STALL; + ep_csr->tx_csrl = MUSB_TXCSRL1_STALL; } else { /* OUT */ - TU_ASSERT(!(ep_csr->rx_csrl & USB_RXCSRL1_RXRDY),); - ep_csr->rx_csrl = USB_RXCSRL1_STALL; + TU_ASSERT(!(ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY),); + ep_csr->rx_csrl = MUSB_RXCSRL1_STALL; } } if (ie) musb_dcd_int_enable(rhport); @@ -815,9 +815,9 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (tu_edpt_dir(ep_addr)) { /* IN */ - ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; + ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT; } else { /* OUT */ - ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; + ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT; } if (ie) musb_dcd_int_enable(rhport); } @@ -838,18 +838,18 @@ void dcd_int_handler(uint8_t rhport) { // TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis); intr_usb &= musb_regs->intr_usben; /* Clear disabled interrupts */ - if (intr_usb & USB_IS_DISCON) { + if (intr_usb & MUSB_IS_DISCON) { } - if (intr_usb & USB_IS_SOF) { + if (intr_usb & MUSB_IS_SOF) { dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); } - if (intr_usb & USB_IS_RESET) { + if (intr_usb & MUSB_IS_RESET) { process_bus_reset(rhport); } - if (intr_usb & USB_IS_RESUME) { + if (intr_usb & MUSB_IS_RESUME) { dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } - if (intr_usb & USB_IS_SUSPEND) { + if (intr_usb & MUSB_IS_SUSPEND) { dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 619eb0108..3415f74b5 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -307,14 +307,14 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ //--------------------------------------------------------------------+ // 0x01: Power -#define USB_POWER_ISOUP 0x0080 // Isochronous Update -#define USB_POWER_SOFTCONN 0x0040 // Soft Connect/Disconnect -#define USB_POWER_HSENAB 0x0020 // High Speed Enable -#define USB_POWER_HSMODE 0x0010 // High Speed Enable -#define USB_POWER_RESET 0x0008 // RESET Signaling -#define USB_POWER_RESUME 0x0004 // RESUME Signaling -#define USB_POWER_SUSPEND 0x0002 // SUSPEND Mode -#define USB_POWER_PWRDNPHY 0x0001 // Power Down PHY +#define MUSB_POWER_ISOUP 0x0080 // Isochronous Update +#define MUSB_POWER_SOFTCONN 0x0040 // Soft Connect/Disconnect +#define MUSB_POWER_HSENAB 0x0020 // High Speed Enable +#define MUSB_POWER_HSMODE 0x0010 // High Speed Enable +#define MUSB_POWER_RESET 0x0008 // RESET Signaling +#define MUSB_POWER_RESUME 0x0004 // RESUME Signaling +#define MUSB_POWER_SUSPEND 0x0002 // SUSPEND Mode +#define MUSB_POWER_PWRDNPHY 0x0001 // Power Down PHY // Interrupt TX/RX Status and Enable: each bit is for an endpoint @@ -340,460 +340,460 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_IS register. +// The following are defines for the bit fields in the MUSB_O_IS register. // //***************************************************************************** -#define USB_IS_VBUSERR 0x0080 // VBUS Error (OTG only) -#define USB_IS_SESREQ 0x0040 // SESSION REQUEST (OTG only) -#define USB_IS_DISCON 0x0020 // Session Disconnect (OTG only) -#define USB_IS_CONN 0x0010 // Session Connect -#define USB_IS_SOF 0x0008 // Start of Frame -#define USB_IS_BABBLE 0x0004 // Babble Detected -#define USB_IS_RESET 0x0004 // RESET Signaling Detected -#define USB_IS_RESUME 0x0002 // RESUME Signaling Detected -#define USB_IS_SUSPEND 0x0001 // SUSPEND Signaling Detected +#define MUSB_IS_VBUSERR 0x0080 // VBUS Error (OTG only) +#define MUSB_IS_SESREQ 0x0040 // SESSION REQUEST (OTG only) +#define MUSB_IS_DISCON 0x0020 // Session Disconnect (OTG only) +#define MUSB_IS_CONN 0x0010 // Session Connect +#define MUSB_IS_SOF 0x0008 // Start of Frame +#define MUSB_IS_BABBLE 0x0004 // Babble Detected +#define MUSB_IS_RESET 0x0004 // RESET Signaling Detected +#define MUSB_IS_RESUME 0x0002 // RESUME Signaling Detected +#define MUSB_IS_SUSPEND 0x0001 // SUSPEND Signaling Detected //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_IE register. +// The following are defines for the bit fields in the MUSB_O_IE register. // //***************************************************************************** -#define USB_IE_VBUSERR 0x0080 // Enable VBUS Error Interrupt (OTG only) -#define USB_IE_SESREQ 0x0040 // Enable Session Request (OTG only) -#define USB_IE_DISCON 0x0020 // Enable Disconnect Interrupt -#define USB_IE_CONN 0x0010 // Enable Connect Interrupt -#define USB_IE_SOF 0x0008 // Enable Start-of-Frame Interrupt -#define USB_IE_BABBLE 0x0004 // Enable Babble Interrupt -#define USB_IE_RESET 0x0004 // Enable RESET Interrupt -#define USB_IE_RESUME 0x0002 // Enable RESUME Interrupt -#define USB_IE_SUSPND 0x0001 // Enable SUSPEND Interrupt +#define MUSB_IE_VBUSERR 0x0080 // Enable VBUS Error Interrupt (OTG only) +#define MUSB_IE_SESREQ 0x0040 // Enable Session Request (OTG only) +#define MUSB_IE_DISCON 0x0020 // Enable Disconnect Interrupt +#define MUSB_IE_CONN 0x0010 // Enable Connect Interrupt +#define MUSB_IE_SOF 0x0008 // Enable Start-of-Frame Interrupt +#define MUSB_IE_BABBLE 0x0004 // Enable Babble Interrupt +#define MUSB_IE_RESET 0x0004 // Enable RESET Interrupt +#define MUSB_IE_RESUME 0x0002 // Enable RESUME Interrupt +#define MUSB_IE_SUSPND 0x0001 // Enable SUSPEND Interrupt //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_FRAME register. +// The following are defines for the bit fields in the MUSB_O_FRAME register. // //***************************************************************************** -#define USB_FRAME_M 0x07FF // Frame Number -#define USB_FRAME_S 0 +#define MUSB_FRAME_M 0x07FF // Frame Number +#define MUSB_FRAME_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TEST register. +// The following are defines for the bit fields in the MUSB_O_TEST register. // //***************************************************************************** -#define USB_TEST_FORCEH 0x0080 // Force Host Mode -#define USB_TEST_FIFOACC 0x0040 // FIFO Access -#define USB_TEST_FORCEFS 0x0020 // Force Full-Speed Mode -#define USB_TEST_FORCEHS 0x0010 // Force High-Speed Mode -#define USB_TEST_TESTPKT 0x0008 // Test Packet Mode Enable -#define USB_TEST_TESTK 0x0004 // Test_K Mode Enable -#define USB_TEST_TESTJ 0x0002 // Test_J Mode Enable -#define USB_TEST_TESTSE0NAK 0x0001 // Test_SE0_NAK Test Mode Enable +#define MUSB_TEST_FORCEH 0x0080 // Force Host Mode +#define MUSB_TEST_FIFOACC 0x0040 // FIFO Access +#define MUSB_TEST_FORCEFS 0x0020 // Force Full-Speed Mode +#define MUSB_TEST_FORCEHS 0x0010 // Force High-Speed Mode +#define MUSB_TEST_TESTPKT 0x0008 // Test Packet Mode Enable +#define MUSB_TEST_TESTK 0x0004 // Test_K Mode Enable +#define MUSB_TEST_TESTJ 0x0002 // Test_J Mode Enable +#define MUSB_TEST_TESTSE0NAK 0x0001 // Test_SE0_NAK Test Mode Enable //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_DEVCTL register. +// The following are defines for the bit fields in the MUSB_O_DEVCTL register. // //***************************************************************************** -#define USB_DEVCTL_DEV 0x0080 // Device Mode (OTG only) -#define USB_DEVCTL_FSDEV 0x0040 // Full-Speed Device Detected -#define USB_DEVCTL_LSDEV 0x0020 // Low-Speed Device Detected -#define USB_DEVCTL_VBUS_M 0x0018 // VBUS Level (OTG only) -#define USB_DEVCTL_VBUS_NONE 0x0000 // Below SessionEnd -#define USB_DEVCTL_VBUS_SEND 0x0008 // Above SessionEnd, below AValid -#define USB_DEVCTL_VBUS_AVALID 0x0010 // Above AValid, below VBUSValid -#define USB_DEVCTL_VBUS_VALID 0x0018 // Above VBUSValid -#define USB_DEVCTL_HOST 0x0004 // Host Mode -#define USB_DEVCTL_HOSTREQ 0x0002 // Host Request (OTG only) -#define USB_DEVCTL_SESSION 0x0001 // Session Start/End (OTG only) +#define MUSB_DEVCTL_DEV 0x0080 // Device Mode (OTG only) +#define MUSB_DEVCTL_FSDEV 0x0040 // Full-Speed Device Detected +#define MUSB_DEVCTL_LSDEV 0x0020 // Low-Speed Device Detected +#define MUSB_DEVCTL_VBUS_M 0x0018 // VBUS Level (OTG only) +#define MUSB_DEVCTL_VBUS_NONE 0x0000 // Below SessionEnd +#define MUSB_DEVCTL_VBUS_SEND 0x0008 // Above SessionEnd, below AValid +#define MUSB_DEVCTL_VBUS_AVALID 0x0010 // Above AValid, below VBUSValid +#define MUSB_DEVCTL_VBUS_VALID 0x0018 // Above VBUSValid +#define MUSB_DEVCTL_HOST 0x0004 // Host Mode +#define MUSB_DEVCTL_HOSTREQ 0x0002 // Host Request (OTG only) +#define MUSB_DEVCTL_SESSION 0x0001 // Session Start/End (OTG only) //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_CCONF register. +// The following are defines for the bit fields in the MUSB_O_CCONF register. // //***************************************************************************** -#define USB_CCONF_TXEDMA 0x0002 // TX Early DMA Enable -#define USB_CCONF_RXEDMA 0x0001 // TX Early DMA Enable +#define MUSB_CCONF_TXEDMA 0x0002 // TX Early DMA Enable +#define MUSB_CCONF_RXEDMA 0x0001 // TX Early DMA Enable //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXFIFOSZ register. +// The following are defines for the bit fields in the MUSB_O_TXFIFOSZ register. // //***************************************************************************** -#define USB_TXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support -#define USB_TXFIFOSZ_SIZE_M 0x000F // Max Packet Size -#define USB_TXFIFOSZ_SIZE_8 0x0000 // 8 -#define USB_TXFIFOSZ_SIZE_16 0x0001 // 16 -#define USB_TXFIFOSZ_SIZE_32 0x0002 // 32 -#define USB_TXFIFOSZ_SIZE_64 0x0003 // 64 -#define USB_TXFIFOSZ_SIZE_128 0x0004 // 128 -#define USB_TXFIFOSZ_SIZE_256 0x0005 // 256 -#define USB_TXFIFOSZ_SIZE_512 0x0006 // 512 -#define USB_TXFIFOSZ_SIZE_1024 0x0007 // 1024 -#define USB_TXFIFOSZ_SIZE_2048 0x0008 // 2048 +#define MUSB_TXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support +#define MUSB_TXFIFOSZ_SIZE_M 0x000F // Max Packet Size +#define MUSB_TXFIFOSZ_SIZE_8 0x0000 // 8 +#define MUSB_TXFIFOSZ_SIZE_16 0x0001 // 16 +#define MUSB_TXFIFOSZ_SIZE_32 0x0002 // 32 +#define MUSB_TXFIFOSZ_SIZE_64 0x0003 // 64 +#define MUSB_TXFIFOSZ_SIZE_128 0x0004 // 128 +#define MUSB_TXFIFOSZ_SIZE_256 0x0005 // 256 +#define MUSB_TXFIFOSZ_SIZE_512 0x0006 // 512 +#define MUSB_TXFIFOSZ_SIZE_1024 0x0007 // 1024 +#define MUSB_TXFIFOSZ_SIZE_2048 0x0008 // 2048 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXFIFOSZ register. +// The following are defines for the bit fields in the MUSB_O_RXFIFOSZ register. // //***************************************************************************** -#define USB_RXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support -#define USB_RXFIFOSZ_SIZE_M 0x000F // Max Packet Size -#define USB_RXFIFOSZ_SIZE_8 0x0000 // 8 -#define USB_RXFIFOSZ_SIZE_16 0x0001 // 16 -#define USB_RXFIFOSZ_SIZE_32 0x0002 // 32 -#define USB_RXFIFOSZ_SIZE_64 0x0003 // 64 -#define USB_RXFIFOSZ_SIZE_128 0x0004 // 128 -#define USB_RXFIFOSZ_SIZE_256 0x0005 // 256 -#define USB_RXFIFOSZ_SIZE_512 0x0006 // 512 -#define USB_RXFIFOSZ_SIZE_1024 0x0007 // 1024 -#define USB_RXFIFOSZ_SIZE_2048 0x0008 // 2048 +#define MUSB_RXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support +#define MUSB_RXFIFOSZ_SIZE_M 0x000F // Max Packet Size +#define MUSB_RXFIFOSZ_SIZE_8 0x0000 // 8 +#define MUSB_RXFIFOSZ_SIZE_16 0x0001 // 16 +#define MUSB_RXFIFOSZ_SIZE_32 0x0002 // 32 +#define MUSB_RXFIFOSZ_SIZE_64 0x0003 // 64 +#define MUSB_RXFIFOSZ_SIZE_128 0x0004 // 128 +#define MUSB_RXFIFOSZ_SIZE_256 0x0005 // 256 +#define MUSB_RXFIFOSZ_SIZE_512 0x0006 // 512 +#define MUSB_RXFIFOSZ_SIZE_1024 0x0007 // 1024 +#define MUSB_RXFIFOSZ_SIZE_2048 0x0008 // 2048 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXFIFOADD +// The following are defines for the bit fields in the MUSB_O_TXFIFOADD // register. // //***************************************************************************** -#define USB_TXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address -#define USB_TXFIFOADD_ADDR_S 0 +#define MUSB_TXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address +#define MUSB_TXFIFOADD_ADDR_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXFIFOADD +// The following are defines for the bit fields in the MUSB_O_RXFIFOADD // register. // //***************************************************************************** -#define USB_RXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address -#define USB_RXFIFOADD_ADDR_S 0 +#define MUSB_RXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address +#define MUSB_RXFIFOADD_ADDR_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_ULPIVBUSCTL +// The following are defines for the bit fields in the MUSB_O_ULPIVBUSCTL // register. // //***************************************************************************** -#define USB_ULPIVBUSCTL_USEEXTVBUSIND 0x0002 // Use External VBUS Indicator -#define USB_ULPIVBUSCTL_USEEXTVBUS 0x0001 // Use External VBUS +#define MUSB_ULPIVBUSCTL_USEEXTVBUSIND 0x0002 // Use External VBUS Indicator +#define MUSB_ULPIVBUSCTL_USEEXTVBUS 0x0001 // Use External VBUS //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_ULPIREGDATA +// The following are defines for the bit fields in the MUSB_O_ULPIREGDATA // register. // //***************************************************************************** -#define USB_ULPIREGDATA_REGDATA_M 0x00FF // Register Data -#define USB_ULPIREGDATA_REGDATA_S 0 +#define MUSB_ULPIREGDATA_REGDATA_M 0x00FF // Register Data +#define MUSB_ULPIREGDATA_REGDATA_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_ULPIREGADDR +// The following are defines for the bit fields in the MUSB_O_ULPIREGADDR // register. // //***************************************************************************** -#define USB_ULPIREGADDR_ADDR_M 0x00FF // Register Address -#define USB_ULPIREGADDR_ADDR_S 0 +#define MUSB_ULPIREGADDR_ADDR_M 0x00FF // Register Address +#define MUSB_ULPIREGADDR_ADDR_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_ULPIREGCTL +// The following are defines for the bit fields in the MUSB_O_ULPIREGCTL // register. // //***************************************************************************** -#define USB_ULPIREGCTL_RDWR 0x0004 // Read/Write Control -#define USB_ULPIREGCTL_REGCMPLT 0x0002 // Register Access Complete -#define USB_ULPIREGCTL_REGACC 0x0001 // Initiate Register Access +#define MUSB_ULPIREGCTL_RDWR 0x0004 // Read/Write Control +#define MUSB_ULPIREGCTL_REGCMPLT 0x0002 // Register Access Complete +#define MUSB_ULPIREGCTL_REGACC 0x0001 // Initiate Register Access //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_EPINFO register. +// The following are defines for the bit fields in the MUSB_O_EPINFO register. // //***************************************************************************** -#define USB_EPINFO_RXEP_M 0x00F0 // RX Endpoints -#define USB_EPINFO_TXEP_M 0x000F // TX Endpoints -#define USB_EPINFO_RXEP_S 4 -#define USB_EPINFO_TXEP_S 0 +#define MUSB_EPINFO_RXEP_M 0x00F0 // RX Endpoints +#define MUSB_EPINFO_TXEP_M 0x000F // TX Endpoints +#define MUSB_EPINFO_RXEP_S 4 +#define MUSB_EPINFO_TXEP_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RAMINFO register. +// The following are defines for the bit fields in the MUSB_O_RAMINFO register. // //***************************************************************************** -#define USB_RAMINFO_DMACHAN_M 0x00F0 // DMA Channels -#define USB_RAMINFO_RAMBITS_M 0x000F // RAM Address Bus Width -#define USB_RAMINFO_DMACHAN_S 4 -#define USB_RAMINFO_RAMBITS_S 0 +#define MUSB_RAMINFO_DMACHAN_M 0x00F0 // DMA Channels +#define MUSB_RAMINFO_RAMBITS_M 0x000F // RAM Address Bus Width +#define MUSB_RAMINFO_DMACHAN_S 4 +#define MUSB_RAMINFO_RAMBITS_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_CONTIM register. +// The following are defines for the bit fields in the MUSB_O_CONTIM register. // //***************************************************************************** -#define USB_CONTIM_WTCON_M 0x00F0 // Connect Wait -#define USB_CONTIM_WTID_M 0x000F // Wait ID -#define USB_CONTIM_WTCON_S 4 -#define USB_CONTIM_WTID_S 0 +#define MUSB_CONTIM_WTCON_M 0x00F0 // Connect Wait +#define MUSB_CONTIM_WTID_M 0x000F // Wait ID +#define MUSB_CONTIM_WTCON_S 4 +#define MUSB_CONTIM_WTID_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_VPLEN register. +// The following are defines for the bit fields in the MUSB_O_VPLEN register. // //***************************************************************************** -#define USB_VPLEN_VPLEN_M 0x00FF // VBUS Pulse Length -#define USB_VPLEN_VPLEN_S 0 +#define MUSB_VPLEN_VPLEN_M 0x00FF // VBUS Pulse Length +#define MUSB_VPLEN_VPLEN_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_HSEOF register. +// The following are defines for the bit fields in the MUSB_O_HSEOF register. // //***************************************************************************** -#define USB_HSEOF_HSEOFG_M 0x00FF // HIgh-Speed End-of-Frame Gap -#define USB_HSEOF_HSEOFG_S 0 +#define MUSB_HSEOF_HSEOFG_M 0x00FF // HIgh-Speed End-of-Frame Gap +#define MUSB_HSEOF_HSEOFG_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_FSEOF register. +// The following are defines for the bit fields in the MUSB_O_FSEOF register. // //***************************************************************************** -#define USB_FSEOF_FSEOFG_M 0x00FF // Full-Speed End-of-Frame Gap -#define USB_FSEOF_FSEOFG_S 0 +#define MUSB_FSEOF_FSEOFG_M 0x00FF // Full-Speed End-of-Frame Gap +#define MUSB_FSEOF_FSEOFG_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_LSEOF register. +// The following are defines for the bit fields in the MUSB_O_LSEOF register. // //***************************************************************************** -#define USB_LSEOF_LSEOFG_M 0x00FF // Low-Speed End-of-Frame Gap -#define USB_LSEOF_LSEOFG_S 0 +#define MUSB_LSEOF_LSEOFG_M 0x00FF // Low-Speed End-of-Frame Gap +#define MUSB_LSEOF_LSEOFG_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_CSRL0 register. +// The following are defines for the bit fields in the MUSB_O_CSRL0 register. // //***************************************************************************** -#define USB_CSRL0_NAKTO 0x0080 // NAK Timeout -#define USB_CSRL0_SETENDC 0x0080 // Setup End Clear -#define USB_CSRL0_STATUS 0x0040 // STATUS Packet -#define USB_CSRL0_RXRDYC 0x0040 // RXRDY Clear -#define USB_CSRL0_REQPKT 0x0020 // Request Packet -#define USB_CSRL0_STALL 0x0020 // Send Stall -#define USB_CSRL0_SETEND 0x0010 // Setup End -#define USB_CSRL0_ERROR 0x0010 // Error -#define USB_CSRL0_DATAEND 0x0008 // Data End -#define USB_CSRL0_SETUP 0x0008 // Setup Packet -#define USB_CSRL0_STALLED 0x0004 // Endpoint Stalled -#define USB_CSRL0_TXRDY 0x0002 // Transmit Packet Ready -#define USB_CSRL0_RXRDY 0x0001 // Receive Packet Ready +#define MUSB_CSRL0_NAKTO 0x0080 // NAK Timeout +#define MUSB_CSRL0_SETENDC 0x0080 // Setup End Clear +#define MUSB_CSRL0_STATUS 0x0040 // STATUS Packet +#define MUSB_CSRL0_RXRDYC 0x0040 // RXRDY Clear +#define MUSB_CSRL0_REQPKT 0x0020 // Request Packet +#define MUSB_CSRL0_STALL 0x0020 // Send Stall +#define MUSB_CSRL0_SETEND 0x0010 // Setup End +#define MUSB_CSRL0_ERROR 0x0010 // Error +#define MUSB_CSRL0_DATAEND 0x0008 // Data End +#define MUSB_CSRL0_SETUP 0x0008 // Setup Packet +#define MUSB_CSRL0_STALLED 0x0004 // Endpoint Stalled +#define MUSB_CSRL0_TXRDY 0x0002 // Transmit Packet Ready +#define MUSB_CSRL0_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_CSRH0 register. +// The following are defines for the bit fields in the MUSB_O_CSRH0 register. // //***************************************************************************** -#define USB_CSRH0_DISPING 0x0008 // PING Disable -#define USB_CSRH0_DTWE 0x0004 // Data Toggle Write Enable -#define USB_CSRH0_DT 0x0002 // Data Toggle -#define USB_CSRH0_FLUSH 0x0001 // Flush FIFO +#define MUSB_CSRH0_DISPING 0x0008 // PING Disable +#define MUSB_CSRH0_DTWE 0x0004 // Data Toggle Write Enable +#define MUSB_CSRH0_DT 0x0002 // Data Toggle +#define MUSB_CSRH0_FLUSH 0x0001 // Flush FIFO //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TYPE0 register. +// The following are defines for the bit fields in the MUSB_O_TYPE0 register. // //***************************************************************************** -#define USB_TYPE0_SPEED_M 0x00C0 // Operating Speed -#define USB_TYPE0_SPEED_HIGH 0x0040 // High -#define USB_TYPE0_SPEED_FULL 0x0080 // Full -#define USB_TYPE0_SPEED_LOW 0x00C0 // Low +#define MUSB_TYPE0_SPEED_M 0x00C0 // Operating Speed +#define MUSB_TYPE0_SPEED_HIGH 0x0040 // High +#define MUSB_TYPE0_SPEED_FULL 0x0080 // Full +#define MUSB_TYPE0_SPEED_LOW 0x00C0 // Low //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_NAKLMT register. +// The following are defines for the bit fields in the MUSB_O_NAKLMT register. // //***************************************************************************** -#define USB_NAKLMT_NAKLMT_M 0x001F // EP0 NAK Limit -#define USB_NAKLMT_NAKLMT_S 0 +#define MUSB_NAKLMT_NAKLMT_M 0x001F // EP0 NAK Limit +#define MUSB_NAKLMT_NAKLMT_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXCSRL1 register. +// The following are defines for the bit fields in the MUSB_O_TXCSRL1 register. // //***************************************************************************** -#define USB_TXCSRL1_NAKTO 0x0080 // NAK Timeout -#define USB_TXCSRL1_CLRDT 0x0040 // Clear Data Toggle -#define USB_TXCSRL1_STALLED 0x0020 // Endpoint Stalled -#define USB_TXCSRL1_STALL 0x0010 // Send STALL -#define USB_TXCSRL1_SETUP 0x0010 // Setup Packet -#define USB_TXCSRL1_FLUSH 0x0008 // Flush FIFO -#define USB_TXCSRL1_ERROR 0x0004 // Error -#define USB_TXCSRL1_UNDRN 0x0004 // Underrun -#define USB_TXCSRL1_FIFONE 0x0002 // FIFO Not Empty -#define USB_TXCSRL1_TXRDY 0x0001 // Transmit Packet Ready +#define MUSB_TXCSRL1_NAKTO 0x0080 // NAK Timeout +#define MUSB_TXCSRL1_CLRDT 0x0040 // Clear Data Toggle +#define MUSB_TXCSRL1_STALLED 0x0020 // Endpoint Stalled +#define MUSB_TXCSRL1_STALL 0x0010 // Send STALL +#define MUSB_TXCSRL1_SETUP 0x0010 // Setup Packet +#define MUSB_TXCSRL1_FLUSH 0x0008 // Flush FIFO +#define MUSB_TXCSRL1_ERROR 0x0004 // Error +#define MUSB_TXCSRL1_UNDRN 0x0004 // Underrun +#define MUSB_TXCSRL1_FIFONE 0x0002 // FIFO Not Empty +#define MUSB_TXCSRL1_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXCSRH1 register. +// The following are defines for the bit fields in the MUSB_O_TXCSRH1 register. // //***************************************************************************** -#define USB_TXCSRH1_AUTOSET 0x0080 // Auto Set -#define USB_TXCSRH1_ISO 0x0040 // Isochronous Transfers -#define USB_TXCSRH1_MODE 0x0020 // Mode -#define USB_TXCSRH1_DMAEN 0x0010 // DMA Request Enable -#define USB_TXCSRH1_FDT 0x0008 // Force Data Toggle -#define USB_TXCSRH1_DMAMOD 0x0004 // DMA Request Mode -#define USB_TXCSRH1_DTWE 0x0002 // Data Toggle Write Enable -#define USB_TXCSRH1_DT 0x0001 // Data Toggle +#define MUSB_TXCSRH1_AUTOSET 0x0080 // Auto Set +#define MUSB_TXCSRH1_ISO 0x0040 // Isochronous Transfers +#define MUSB_TXCSRH1_MODE 0x0020 // Mode +#define MUSB_TXCSRH1_DMAEN 0x0010 // DMA Request Enable +#define MUSB_TXCSRH1_FDT 0x0008 // Force Data Toggle +#define MUSB_TXCSRH1_DMAMOD 0x0004 // DMA Request Mode +#define MUSB_TXCSRH1_DTWE 0x0002 // Data Toggle Write Enable +#define MUSB_TXCSRH1_DT 0x0001 // Data Toggle //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXCSRL1 register. +// The following are defines for the bit fields in the MUSB_O_RXCSRL1 register. // //***************************************************************************** -#define USB_RXCSRL1_CLRDT 0x0080 // Clear Data Toggle -#define USB_RXCSRL1_STALLED 0x0040 // Endpoint Stalled -#define USB_RXCSRL1_STALL 0x0020 // Send STALL -#define USB_RXCSRL1_REQPKT 0x0020 // Request Packet -#define USB_RXCSRL1_FLUSH 0x0010 // Flush FIFO -#define USB_RXCSRL1_DATAERR 0x0008 // Data Error -#define USB_RXCSRL1_NAKTO 0x0008 // NAK Timeout -#define USB_RXCSRL1_OVER 0x0004 // Overrun -#define USB_RXCSRL1_ERROR 0x0004 // Error -#define USB_RXCSRL1_FULL 0x0002 // FIFO Full -#define USB_RXCSRL1_RXRDY 0x0001 // Receive Packet Ready +#define MUSB_RXCSRL1_CLRDT 0x0080 // Clear Data Toggle +#define MUSB_RXCSRL1_STALLED 0x0040 // Endpoint Stalled +#define MUSB_RXCSRL1_STALL 0x0020 // Send STALL +#define MUSB_RXCSRL1_REQPKT 0x0020 // Request Packet +#define MUSB_RXCSRL1_FLUSH 0x0010 // Flush FIFO +#define MUSB_RXCSRL1_DATAERR 0x0008 // Data Error +#define MUSB_RXCSRL1_NAKTO 0x0008 // NAK Timeout +#define MUSB_RXCSRL1_OVER 0x0004 // Overrun +#define MUSB_RXCSRL1_ERROR 0x0004 // Error +#define MUSB_RXCSRL1_FULL 0x0002 // FIFO Full +#define MUSB_RXCSRL1_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXCSRH1 register. +// The following are defines for the bit fields in the MUSB_O_RXCSRH1 register. // //***************************************************************************** -#define USB_RXCSRH1_AUTOCL 0x0080 // Auto Clear -#define USB_RXCSRH1_AUTORQ 0x0040 // Auto Request -#define USB_RXCSRH1_ISO 0x0040 // Isochronous Transfers -#define USB_RXCSRH1_DMAEN 0x0020 // DMA Request Enable -#define USB_RXCSRH1_DISNYET 0x0010 // Disable NYET -#define USB_RXCSRH1_PIDERR 0x0010 // PID Error -#define USB_RXCSRH1_DMAMOD 0x0008 // DMA Request Mode -#define USB_RXCSRH1_DTWE 0x0004 // Data Toggle Write Enable -#define USB_RXCSRH1_DT 0x0002 // Data Toggle -#define USB_RXCSRH1_INCOMPRX 0x0001 // Incomplete RX Transmission Status +#define MUSB_RXCSRH1_AUTOCL 0x0080 // Auto Clear +#define MUSB_RXCSRH1_AUTORQ 0x0040 // Auto Request +#define MUSB_RXCSRH1_ISO 0x0040 // Isochronous Transfers +#define MUSB_RXCSRH1_DMAEN 0x0020 // DMA Request Enable +#define MUSB_RXCSRH1_DISNYET 0x0010 // Disable NYET +#define MUSB_RXCSRH1_PIDERR 0x0010 // PID Error +#define MUSB_RXCSRH1_DMAMOD 0x0008 // DMA Request Mode +#define MUSB_RXCSRH1_DTWE 0x0004 // Data Toggle Write Enable +#define MUSB_RXCSRH1_DT 0x0002 // Data Toggle +#define MUSB_RXCSRH1_INCOMPRX 0x0001 // Incomplete RX Transmission Status //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXTYPE1 register. +// The following are defines for the bit fields in the MUSB_O_TXTYPE1 register. // //***************************************************************************** -#define USB_TXTYPE1_SPEED_M 0x00C0 // Operating Speed -#define USB_TXTYPE1_SPEED_DFLT 0x0000 // Default -#define USB_TXTYPE1_SPEED_HIGH 0x0040 // High -#define USB_TXTYPE1_SPEED_FULL 0x0080 // Full -#define USB_TXTYPE1_SPEED_LOW 0x00C0 // Low -#define USB_TXTYPE1_PROTO_M 0x0030 // Protocol -#define USB_TXTYPE1_PROTO_CTRL 0x0000 // Control -#define USB_TXTYPE1_PROTO_ISOC 0x0010 // Isochronous -#define USB_TXTYPE1_PROTO_BULK 0x0020 // Bulk -#define USB_TXTYPE1_PROTO_INT 0x0030 // Interrupt -#define USB_TXTYPE1_TEP_M 0x000F // Target Endpoint Number -#define USB_TXTYPE1_TEP_S 0 +#define MUSB_TXTYPE1_SPEED_M 0x00C0 // Operating Speed +#define MUSB_TXTYPE1_SPEED_DFLT 0x0000 // Default +#define MUSB_TXTYPE1_SPEED_HIGH 0x0040 // High +#define MUSB_TXTYPE1_SPEED_FULL 0x0080 // Full +#define MUSB_TXTYPE1_SPEED_LOW 0x00C0 // Low +#define MUSB_TXTYPE1_PROTO_M 0x0030 // Protocol +#define MUSB_TXTYPE1_PROTO_CTRL 0x0000 // Control +#define MUSB_TXTYPE1_PROTO_ISOC 0x0010 // Isochronous +#define MUSB_TXTYPE1_PROTO_BULK 0x0020 // Bulk +#define MUSB_TXTYPE1_PROTO_INT 0x0030 // Interrupt +#define MUSB_TXTYPE1_TEP_M 0x000F // Target Endpoint Number +#define MUSB_TXTYPE1_TEP_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXINTERVAL1 +// The following are defines for the bit fields in the MUSB_O_TXINTERVAL1 // register. // //***************************************************************************** -#define USB_TXINTERVAL1_NAKLMT_M 0x00FF // NAK Limit -#define USB_TXINTERVAL1_TXPOLL_M 0x00FF // TX Polling -#define USB_TXINTERVAL1_TXPOLL_S 0 -#define USB_TXINTERVAL1_NAKLMT_S 0 +#define MUSB_TXINTERVAL1_NAKLMT_M 0x00FF // NAK Limit +#define MUSB_TXINTERVAL1_TXPOLL_M 0x00FF // TX Polling +#define MUSB_TXINTERVAL1_TXPOLL_S 0 +#define MUSB_TXINTERVAL1_NAKLMT_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXTYPE1 register. +// The following are defines for the bit fields in the MUSB_O_RXTYPE1 register. // //***************************************************************************** -#define USB_RXTYPE1_SPEED_M 0x00C0 // Operating Speed -#define USB_RXTYPE1_SPEED_DFLT 0x0000 // Default -#define USB_RXTYPE1_SPEED_HIGH 0x0040 // High -#define USB_RXTYPE1_SPEED_FULL 0x0080 // Full -#define USB_RXTYPE1_SPEED_LOW 0x00C0 // Low -#define USB_RXTYPE1_PROTO_M 0x0030 // Protocol -#define USB_RXTYPE1_PROTO_CTRL 0x0000 // Control -#define USB_RXTYPE1_PROTO_ISOC 0x0010 // Isochronous -#define USB_RXTYPE1_PROTO_BULK 0x0020 // Bulk -#define USB_RXTYPE1_PROTO_INT 0x0030 // Interrupt -#define USB_RXTYPE1_TEP_M 0x000F // Target Endpoint Number -#define USB_RXTYPE1_TEP_S 0 +#define MUSB_RXTYPE1_SPEED_M 0x00C0 // Operating Speed +#define MUSB_RXTYPE1_SPEED_DFLT 0x0000 // Default +#define MUSB_RXTYPE1_SPEED_HIGH 0x0040 // High +#define MUSB_RXTYPE1_SPEED_FULL 0x0080 // Full +#define MUSB_RXTYPE1_SPEED_LOW 0x00C0 // Low +#define MUSB_RXTYPE1_PROTO_M 0x0030 // Protocol +#define MUSB_RXTYPE1_PROTO_CTRL 0x0000 // Control +#define MUSB_RXTYPE1_PROTO_ISOC 0x0010 // Isochronous +#define MUSB_RXTYPE1_PROTO_BULK 0x0020 // Bulk +#define MUSB_RXTYPE1_PROTO_INT 0x0030 // Interrupt +#define MUSB_RXTYPE1_TEP_M 0x000F // Target Endpoint Number +#define MUSB_RXTYPE1_TEP_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXINTERVAL1 +// The following are defines for the bit fields in the MUSB_O_RXINTERVAL1 // register. // //***************************************************************************** -#define USB_RXINTERVAL1_TXPOLL_M 0x00FF // RX Polling -#define USB_RXINTERVAL1_NAKLMT_M 0x00FF // NAK Limit -#define USB_RXINTERVAL1_TXPOLL_S 0 -#define USB_RXINTERVAL1_NAKLMT_S 0 +#define MUSB_RXINTERVAL1_TXPOLL_M 0x00FF // RX Polling +#define MUSB_RXINTERVAL1_NAKLMT_M 0x00FF // NAK Limit +#define MUSB_RXINTERVAL1_TXPOLL_S 0 +#define MUSB_RXINTERVAL1_NAKLMT_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_DMACTL0 register. +// The following are defines for the bit fields in the MUSB_O_DMACTL0 register. // //***************************************************************************** -#define USB_DMACTL0_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL0_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL0_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL0_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified +#define MUSB_DMACTL0_BRSTM_M 0x0600 // Burst Mode +#define MUSB_DMACTL0_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define MUSB_DMACTL0_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define MUSB_DMACTL0_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL0_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or +#define MUSB_DMACTL0_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL0_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL0_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL0_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL0_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL0_DIR 0x0002 // DMA Direction -#define USB_DMACTL0_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL0_EP_S 4 +#define MUSB_DMACTL0_ERR 0x0100 // Bus Error Bit +#define MUSB_DMACTL0_EP_M 0x00F0 // Endpoint number +#define MUSB_DMACTL0_IE 0x0008 // DMA Interrupt Enable +#define MUSB_DMACTL0_MODE 0x0004 // DMA Transfer Mode +#define MUSB_DMACTL0_DIR 0x0002 // DMA Direction +#define MUSB_DMACTL0_ENABLE 0x0001 // DMA Transfer Enable +#define MUSB_DMACTL0_EP_S 4 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_DMAADDR0 register. +// The following are defines for the bit fields in the MUSB_O_DMAADDR0 register. // //***************************************************************************** -#define USB_DMAADDR0_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR0_ADDR_S 2 +#define MUSB_DMAADDR0_ADDR_M 0xFFFFFFFC // DMA Address +#define MUSB_DMAADDR0_ADDR_S 2 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_DMACOUNT0 +// The following are defines for the bit fields in the MUSB_O_DMACOUNT0 // register. // //***************************************************************************** -#define USB_DMACOUNT0_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT0_COUNT_S 2 +#define MUSB_DMACOUNT0_COUNT_M 0xFFFFFFFC // DMA Count +#define MUSB_DMACOUNT0_COUNT_S 2 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_CTO register. +// The following are defines for the bit fields in the MUSB_O_CTO register. // //***************************************************************************** -#define USB_CTO_CCTV_M 0xFFFF // Configurable Chirp Timeout Value -#define USB_CTO_CCTV_S 0 +#define MUSB_CTO_CCTV_M 0xFFFF // Configurable Chirp Timeout Value +#define MUSB_CTO_CCTV_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_HHSRTN register. +// The following are defines for the bit fields in the MUSB_O_HHSRTN register. // //***************************************************************************** -#define USB_HHSRTN_HHSRTN_M 0xFFFF // HIgh Speed to UTM Operating +#define MUSB_HHSRTN_HHSRTN_M 0xFFFF // HIgh Speed to UTM Operating // Delay -#define USB_HHSRTN_HHSRTN_S 0 +#define MUSB_HHSRTN_HHSRTN_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_HSBT register. +// The following are defines for the bit fields in the MUSB_O_HSBT register. // //***************************************************************************** -#define USB_HSBT_HSBT_M 0x000F // High Speed Timeout Adder -#define USB_HSBT_HSBT_S 0 +#define MUSB_HSBT_HSBT_M 0x000F // High Speed Timeout Adder +#define MUSB_HSBT_HSBT_S 0 #ifdef __cplusplus } -- cgit v1.3.1 From 76eb2f506642968b2b0079326483905e79d20d2f Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 18 Aug 2024 16:34:58 +0700 Subject: more musb update --- src/portable/mentor/musb/dcd_musb.c | 79 +++++++++++++++++++---------------- src/portable/mentor/musb/musb_max32.h | 12 ++---- src/portable/mentor/musb/musb_type.h | 14 ++++--- 3 files changed, 54 insertions(+), 51 deletions(-) diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 3fd4d953a..585480772 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -643,8 +643,7 @@ void dcd_sof_enable(uint8_t rhport, bool en) //--------------------------------------------------------------------+ // Configure endpoint's registers according to descriptor -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) -{ +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir_in = tu_edpt_dir(ep_addr); @@ -662,22 +661,30 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); const uint8_t is_rx = 1 - dir_in; - ep_csr->maxp_csr[is_rx].maxp = mps; - ep_csr->maxp_csr[is_rx].csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? MUSB_RXCSRH1_ISO : 0; + musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[is_rx]; + maxp_csr->maxp = mps; + maxp_csr->csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? MUSB_RXCSRH1_ISO : 0; + // flush and reset data toggle uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx); - if (ep_csr->maxp_csr[is_rx].csrl & MUSB_CSRL_PACKET_READY(is_rx)) { + if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) { csrl |= MUSB_CSRL_FLUSH_FIFO(is_rx); } - ep_csr->maxp_csr[is_rx].csrl = csrl; + maxp_csr->csrl = csrl; + musb->intren_ep[is_rx] |= TU_BIT(epn); - /* Setup FIFO */ fifo_configure(musb, epn, dir_in, mps); return true; } +// bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { +// } +// +// bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { +// } + void dcd_edpt_close_all(uint8_t rhport) { musb_regs_t* musb = MUSB_REGS(rhport); @@ -688,23 +695,20 @@ void dcd_edpt_close_all(uint8_t rhport) musb->intr_rxen = 0; for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { musb_ep_csr_t* ep_csr = get_ep_csr(musb, i); - ep_csr->tx_maxp = 0; - ep_csr->tx_csrh = 0; - if (ep_csr->tx_csrl & MUSB_TXCSRL1_TXRDY) - ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT | MUSB_TXCSRL1_FLUSH; - else - ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT; + for (unsigned d = 0; d < 2; d++) { + musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[d]; + maxp_csr->maxp = 0; + maxp_csr->csrh = 0; + + // flush and reset data toggle + uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(d); + if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) { + csrl |= MUSB_CSRL_FLUSH_FIFO(d); + } + maxp_csr->csrl = csrl; - ep_csr->rx_maxp = 0; - ep_csr->rx_csrh = 0; - if (ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY) { - ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT | MUSB_RXCSRL1_FLUSH; - } else { - ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT; + fifo_reset(musb, i, 1-d); } - - fifo_reset(musb, i, 0); - fifo_reset(musb, i, 1); } #if MUSB_CFG_DYNAMIC_FIFO @@ -755,12 +759,14 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t unsigned const epnum = tu_edpt_number(ep_addr); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); + if (epnum) { _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); } else { ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); } + if (ie) musb_dcd_int_enable(rhport); return ret; } @@ -783,11 +789,13 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ // Stall endpoint void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { - unsigned const epn = tu_edpt_number(ep_addr); unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); + + unsigned const epn = tu_edpt_number(ep_addr); musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); - musb_dcd_int_disable(rhport); + if (0 == epn) { if (!ep_addr) { /* Ignore EP80 */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; @@ -795,13 +803,10 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { ep_csr->csr0l = MUSB_CSRL0_STALL; } } else { - if (tu_edpt_dir(ep_addr)) { /* IN */ - ep_csr->tx_csrl = MUSB_TXCSRL1_STALL; - } else { /* OUT */ - TU_ASSERT(!(ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY),); - ep_csr->rx_csrl = MUSB_RXCSRL1_STALL; - } + const uint8_t is_rx = 1 - tu_edpt_dir(ep_addr); + ep_csr->maxp_csr[is_rx].csrl = MUSB_CSRL_SEND_STALL(is_rx); } + if (ie) musb_dcd_int_enable(rhport); } @@ -809,16 +814,16 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); + unsigned const epn = tu_edpt_number(ep_addr); musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); - unsigned const ie = musb_dcd_get_int_enable(rhport); - musb_dcd_int_disable(rhport); - if (tu_edpt_dir(ep_addr)) { /* IN */ - ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT; - } else { /* OUT */ - ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT; - } + const uint8_t is_rx = 1 - tu_edpt_dir(ep_addr); + + ep_csr->maxp_csr[is_rx].csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx); + if (ie) musb_dcd_int_enable(rhport); } diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 38e80f680..35849b5f8 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -47,18 +47,15 @@ static const IRQn_Type musb_irqs[] = { USB_IRQn }; -TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_enable(uint8_t rhport) { +TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_enable(uint8_t rhport) { NVIC_EnableIRQ(musb_irqs[rhport]); } -TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_disable(uint8_t rhport) { +TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_disable(uint8_t rhport) { NVIC_DisableIRQ(musb_irqs[rhport]); } -TU_ATTR_ALWAYS_INLINE -static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) { +TU_ATTR_ALWAYS_INLINE static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) { #ifdef NVIC_GetEnableIRQ // only defined in CMSIS 5 return NVIC_GetEnableIRQ(musb_irqs[rhport]); #else @@ -67,8 +64,7 @@ static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) { #endif } -TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_clear(uint8_t rhport) { +TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_clear(uint8_t rhport) { NVIC_ClearPendingIRQ(musb_irqs[rhport]); } diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 3415f74b5..f8a66acce 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -83,6 +83,12 @@ #define __R volatile const #endif +typedef struct TU_ATTR_PACKED { + __IO uint16_t maxp; // 0x00, 0x04: MAXP + __IO uint8_t csrl; // 0x02, 0x06: CSRL + __IO uint8_t csrh; // 0x03, 0x07: CSRH +}musb_ep_maxp_csr_t; + // 0: TX (device IN, host OUT) // 1: RX (device OUT, host IN) typedef struct TU_ATTR_PACKED { @@ -103,11 +109,7 @@ typedef struct TU_ATTR_PACKED { __IO uint8_t rx_csrh; // 0x07: RX CSRH }; - struct { - __IO uint16_t maxp; // 0x00: MAXP - __IO uint8_t csrl; // 0x02: CSRL - __IO uint8_t csrh; // 0x03: CSRH - }maxp_csr[2]; + musb_ep_maxp_csr_t maxp_csr[2]; }; union { @@ -330,7 +332,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ #define MUSB_CSRL_PACKET_READY(_rx) (1u << 0) #define MUSB_CSRL_FLUSH_FIFO(_rx) (1u << ((_rx) ? 4 : 3)) #define MUSB_CSRL_SEND_STALL(_rx) (1u << ((_rx) ? 5 : 4)) -#define MUSB_CSRL_SENT_STALL(_rx) (1u << ((_rx) ? 6 : 5)) +#define MUSB_CSRL_STALLED(_rx) (1u << ((_rx) ? 6 : 5)) #define MUSB_CSRL_CLEAR_DATA_TOGGLE(_rx) (1u << ((_rx) ? 7 : 6)) // 0x13, 0x17: TX/RX CSRH -- cgit v1.3.1 From e345380723051ac3342a724660e877d7b2dad2fb Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 18 Aug 2024 17:15:07 +0700 Subject: add flash_openocd_adi() for use with max32 add feather max32666 to the hil pool --- hw/bsp/family_support.cmake | 19 +++++++++++++++++++ hw/bsp/max32650/family.cmake | 2 ++ hw/bsp/max32666/family.cmake | 16 ++-------------- test/hil/hil_test.py | 12 +++++++++++- test/hil/rpi.json | 7 +++++++ 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 4a31f6218..1df8a6f53 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -480,6 +480,25 @@ function(family_flash_openocd_wch TARGET) endfunction() +# Add flash openocd adi (Analog Devices) target +# included with msdk or compiled from release branch of https://github.com/analogdevicesinc/openocd +function(family_flash_openocd_adi TARGET) + if (DEFINED $ENV{MAXIM_PATH}) + # use openocd from msdk + set(OPENOCD ENV{MAXIM_PATH}/Tools/OpenOCD/openocd) + set(OPENOCD_OPTION2 "-s ENV{MAXIM_PATH}/Tools/OpenOCD/scripts") + else() + # compiled from source + if (NOT DEFINED OPENOCD_ADI_PATH) + set(OPENOCD_ADI_PATH $ENV{HOME}/app/openocd_adi) + endif () + set(OPENOCD ${OPENOCD_ADI_PATH}/src/openocd) + set(OPENOCD_OPTION2 "-s ${OPENOCD_ADI_PATH}/tcl") + endif () + + family_flash_openocd(${TARGET}) +endfunction() + # Add flash with https://github.com/ch32-rs/wlink function(family_flash_wlink_rs TARGET) if (NOT DEFINED WLINK_RS) diff --git a/hw/bsp/max32650/family.cmake b/hw/bsp/max32650/family.cmake index 8c4f286a2..e05bd7652 100644 --- a/hw/bsp/max32650/family.cmake +++ b/hw/bsp/max32650/family.cmake @@ -14,6 +14,7 @@ set(LD_FILE_Clang ${LD_FILE_GNU}) set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(JLINK_DEVICE max32650) +set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -f target/max32650.cfg") set(FAMILY_MCUS MAX32650 CACHE INTERNAL "") @@ -150,6 +151,7 @@ function(family_configure_example TARGET RTOS) # Add the optional MSDK OpenOCD flashing family_flash_msdk(${TARGET}) + family_flash_openocd_adi(${TARGET}) endfunction() function(family_flash_msdk TARGET) diff --git a/hw/bsp/max32666/family.cmake b/hw/bsp/max32666/family.cmake index 4a3f1a428..fb8c32295 100644 --- a/hw/bsp/max32666/family.cmake +++ b/hw/bsp/max32666/family.cmake @@ -15,6 +15,7 @@ set(LD_FILE_Clang ${LD_FILE_GNU}) set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(JLINK_DEVICE max32666) +set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -f target/max32665.cfg") set(FAMILY_MCUS MAX32666 CACHE INTERNAL "") @@ -142,18 +143,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_jlink(${TARGET}) - family_flash_msdk(${TARGET}) -endfunction() - -# Add flash msdk target -function(family_flash_msdk TARGET) - set(MAXIM_PATH "$ENV{MAXIM_PATH}") - - add_custom_target(${TARGET}-msdk - DEPENDS ${TARGET} - COMMAND ${MAXIM_PATH}/Tools/OpenOCD/openocd -s ${MAXIM_PATH}/Tools/OpenOCD/scripts - -f interface/cmsis-dap.cfg -f target/max32665.cfg - -c "program $ verify; init; reset; exit" - VERBATIM - ) + family_flash_openocd_adi(${TARGET}) endfunction() diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 1d5f98e5c..e5900c616 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -173,10 +173,20 @@ echo "Ready for Remote Connections" with open(f_wch, 'w') as file: file.write(cfg_content) - ret = run_cmd(f'openocd_wch -c "adapter serial {board["flasher_sn"]}" -f {f_wch} -c "program {firmware}.elf reset exit"') + ret = run_cmd(f'openocd_wch -c "adapter serial {board["flasher_sn"]}" -f {f_wch} ' + f'-c "program {firmware}.elf reset exit"') return ret +def flash_openocd_adi(board, firmware): + openocd_adi_script_path = f'{os.getenv("HOME")}/app/openocd_adi/tcl' + if not os.path.exists(openocd_adi_script_path): + openocd_adi_script_path = '/home/pi/openocd_adi/tcl' + + ret = run_cmd(f'openocd_adi -c "adapter serial {board["flasher_sn"]}" -s {openocd_adi_script_path} ' + f'{board["flasher_args"]} -c "program {firmware}.elf reset exit"') + return ret + def flash_wlink_rs(board, firmware): # wlink use index for probe selection and lacking usb serial support ret = run_cmd(f'wlink flash {firmware}.elf') diff --git a/test/hil/rpi.json b/test/hil/rpi.json index b7d36c543..a10fa76bd 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -14,6 +14,13 @@ "flasher_sn": "E6614C311B597D32", "flasher_args": "-f interface/cmsis-dap.cfg -f target/atsame5x.cfg -c \"adapter speed 5000\"" }, + { + "name": "max32666fthr", + "uid": "0C81464124010B20FF0A08CC2C", + "flasher": "openocd_adi", + "flasher_sn": "040917023bffc88100000000000000000000000097969906", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/max32665.cfg" + }, { "name": "lpcxpresso11u37", "uid": "17121919", -- cgit v1.3.1 From 8fdd8d9a7b83bfb79ac9a02142592d7ee4948b83 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 19 Aug 2024 11:59:41 +0700 Subject: implement dcd_edpt_iso_alloc/dcd_edpt_iso_activate for musb. video_capture example with iso kind of work but not smoothly. audio example does not seems to work as expected --- hw/bsp/max32690/family.cmake | 1 + src/common/tusb_mcu.h | 3 +- src/device/dcd.h | 15 +-- src/device/usbd.c | 18 +++- src/portable/mentor/musb/dcd_musb.c | 198 ++++++++++++++++++++--------------- src/portable/mentor/musb/musb_ti.h | 145 +------------------------ src/portable/mentor/musb/musb_type.h | 56 +--------- 7 files changed, 147 insertions(+), 289 deletions(-) diff --git a/hw/bsp/max32690/family.cmake b/hw/bsp/max32690/family.cmake index 58647e432..736ca8eac 100644 --- a/hw/bsp/max32690/family.cmake +++ b/hw/bsp/max32690/family.cmake @@ -15,6 +15,7 @@ set(LD_FILE_Clang ${LD_FILE_GNU}) set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(JLINK_DEVICE max32690) +set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -f target/max32690.cfg") set(FAMILY_MCUS MAX32690 CACHE INTERNAL "") diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index b7cbd83df..e86f55c1d 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -518,7 +518,8 @@ #define TU_ATTR_FAST_FUNC #endif -#if defined(TUP_USBIP_DWC2) || defined(TUP_USBIP_FSDEV) +// USBIP that support ISO alloc & activate API +#if defined(TUP_USBIP_DWC2) || defined(TUP_USBIP_FSDEV) || defined(TUP_USBIP_MUSB) #define TUP_DCD_EDPT_ISO_ALLOC #endif diff --git a/src/device/dcd.h b/src/device/dcd.h index 41e0fbee3..66fae0802 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -157,10 +157,6 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc // required for multiple configuration support. void dcd_edpt_close_all (uint8_t rhport); -// Close an endpoint. -// Since it is weak, caller must TU_ASSERT this function's existence before calling it. -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) TU_ATTR_WEAK; - // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); @@ -175,12 +171,19 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr); // This API never calls with control endpoints, since it is auto cleared when receiving setup packet void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); +#ifdef TUP_DCD_EDPT_ISO_ALLOC // Allocate packet buffer used by ISO endpoints // Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering -TU_ATTR_WEAK bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size); +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size); // Configure and enable an ISO endpoint according to descriptor -TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); + +#else +// Close an endpoint. +void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr); + +#endif //--------------------------------------------------------------------+ // Event API (implemented by stack) diff --git a/src/device/usbd.c b/src/device/usbd.c index 7089e9cf1..d6f69fc24 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1418,6 +1418,10 @@ bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr) { * In progress transfers on this EP may be delivered after this call. */ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) { +#ifdef TUP_DCD_EDPT_ISO_ALLOC + (void) rhport; (void) ep_addr; + // ISO alloc/activate Should be used instead +#else rhport = _usbd_rhport; TU_ASSERT(dcd_edpt_close, /**/); @@ -1430,6 +1434,7 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) { _usbd_dev.ep_status[epnum][dir].stalled = 0; _usbd_dev.ep_status[epnum][dir].busy = 0; _usbd_dev.ep_status[epnum][dir].claimed = 0; +#endif return; } @@ -1452,21 +1457,24 @@ void usbd_sof_enable(uint8_t rhport, sof_consumer_t consumer, bool en) { } bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { +#ifdef TUP_DCD_EDPT_ISO_ALLOC rhport = _usbd_rhport; - TU_ASSERT(dcd_edpt_iso_alloc); TU_ASSERT(tu_edpt_number(ep_addr) < CFG_TUD_ENDPPOINT_MAX); - return dcd_edpt_iso_alloc(rhport, ep_addr, largest_packet_size); +#else + (void) rhport; (void) ep_addr; (void) largest_packet_size; + return false; +#endif } bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) { +#ifdef TUP_DCD_EDPT_ISO_ALLOC rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(desc_ep->bEndpointAddress); uint8_t const dir = tu_edpt_dir(desc_ep->bEndpointAddress); - TU_ASSERT(dcd_edpt_iso_activate); TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX); TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) _usbd_dev.speed)); @@ -1474,6 +1482,10 @@ bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) _usbd_dev.ep_status[epnum][dir].busy = 0; _usbd_dev.ep_status[epnum][dir].claimed = 0; return dcd_edpt_iso_activate(rhport, desc_ep); +#else + (void) rhport; (void) desc_ep; + return false; +#endif } #endif diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 585480772..dc2753ea6 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -94,64 +94,71 @@ static dcd_data_t _dcd; // First 64 bytes are reserved for EP0 static uint32_t alloced_fifo_bytes; -TU_ATTR_ALWAYS_INLINE static inline void fifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { +// ffsize is log2(mps) - 3 (round up) +TU_ATTR_ALWAYS_INLINE static inline uint8_t hwfifo_byte2size(uint16_t nbytes) { + uint8_t ffsize = 28 - tu_min8(28, __builtin_clz(nbytes)); + // round up to the next power of 2 + if ((8u << ffsize) < nbytes) { + ++ffsize; + } + + return ffsize; +} + +// index register is already set +TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { + (void) epnum; const uint8_t is_rx = 1 - dir_in; - musb->index = epnum; musb->fifo_size[is_rx] = 0; musb->fifo_addr[is_rx] = 0; } -TU_ATTR_ALWAYS_INLINE static inline bool fifo_configure(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps) { - // ffsize is log2(mps) - 3 (round up) - uint8_t ffsize = 28 - tu_min8(28, __builtin_clz(mps)); - // round up to the next power of 2 - if ((8u << ffsize) < mps) { - ++ffsize; - mps = 8 << ffsize; +// index register is already set +TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps, bool double_packet) { + (void) epnum; + uint8_t ffsize = hwfifo_byte2size(mps); + mps = 8 << ffsize; // round up to the next power of 2 + + if (double_packet) { + ffsize |= MUSB_FIFOSZ_DOUBLE_PACKET; + mps <<= 1; } TU_ASSERT(alloced_fifo_bytes + mps <= MUSB_CFG_DYNAMIC_FIFO_SIZE); const uint8_t is_rx = 1 - dir_in; - musb->index = epnum; + musb->fifo_addr[is_rx] = alloced_fifo_bytes / 8; musb->fifo_size[is_rx] = ffsize; alloced_fifo_bytes += mps; - return true; } #else -TU_ATTR_ALWAYS_INLINE static inline void fifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { - const uint8_t is_rx = 1 - dir_in; - musb->index = epnum; - #if defined(TUP_USBIP_MUSB_ADI) - // Analog have custom double buffered in csrh register, disable it - musb->indexed_csr.maxp_csr[is_rx].csrh |= MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); - #else - // disable double bufeffered in extended register - #endif +// index register is already set +TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { + (void) musb; (void) epnum; (void) dir_in; + // nothing to do for static FIFO } -TU_ATTR_ALWAYS_INLINE static inline bool fifo_configure(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps) { - (void) mps; - const uint8_t is_rx = 1 - dir_in; - musb->index = epnum; - - uint8_t csrh = 0; - -#if defined(TUP_USBIP_MUSB_ADI) - csrh = MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); -#endif +// index register is already set +TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps, + bool double_packet) { + (void) epnum; (void) dir_in; (void) mps; -#if MUSB_CFG_SHARED_FIFO - if (dir_in) { - csrh |= MUSB_CSRH_TX_MODE; + if (!double_packet) { + #if defined(TUP_USBIP_MUSB_ADI) + const uint8_t is_rx = 1 - dir_in; + musb->indexed_csr.maxp_csr[is_rx].csrh |= MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); + #else + if (is_rx) { + musb->rx_doulbe_packet_disable |= 1u << epnum; + } else { + musb->tx_double_packet_disable |= 1u << epnum; + } + #endif } -#endif - - musb->indexed_csr.maxp_csr[is_rx].csrh |= csrh; return true; } @@ -538,8 +545,9 @@ static void process_bus_reset(uint8_t rhport) { /* Clear FIFO settings */ for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - fifo_reset(musb, i, 0); - fifo_reset(musb, i, 1); + musb->index = i; + hwfifo_reset(musb, i, 0); + hwfifo_reset(musb, i, 1); } dcd_event_bus_reset(rhport, (musb->power & MUSB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); } @@ -641,17 +649,18 @@ void dcd_sof_enable(uint8_t rhport, bool en) //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ +// static void edpt_setup(musb_regs_t* musb, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_size){ +// const unsigned epn = tu_edpt_number(ep_addr); +// const unsigned dir_in = tu_edpt_dir(ep_addr); +// } // Configure endpoint's registers according to descriptor bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir_in = tu_edpt_dir(ep_addr); - const unsigned xfer = ep_desc->bmAttributes.xfer; const unsigned mps = tu_edpt_packet_size(ep_desc); - TU_ASSERT(epn < TUP_DCD_ENDPOINT_MAX); - pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; pipe->buf = NULL; pipe->length = 0; @@ -659,11 +668,16 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { musb_regs_t* musb = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); - const uint8_t is_rx = 1 - dir_in; musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[is_rx]; + maxp_csr->maxp = mps; - maxp_csr->csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? MUSB_RXCSRH1_ISO : 0; + maxp_csr->csrh = 0; +#if MUSB_CFG_SHARED_FIFO + if (dir_in) { + maxp_csr->csrh |= MUSB_CSRH_TX_MODE; + } +#endif // flush and reset data toggle uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx); @@ -672,18 +686,65 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { } maxp_csr->csrl = csrl; + TU_ASSERT(hwfifo_config(musb, epn, dir_in, mps, false)); musb->intren_ep[is_rx] |= TU_BIT(epn); - fifo_configure(musb, epn, dir_in, mps); - return true; } -// bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { -// } -// -// bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { -// } +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); + musb_regs_t* musb = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); + const uint8_t is_rx = 1 - dir_in; + ep_csr->maxp_csr[is_rx].csrh = 0; + return hwfifo_config(musb, epn, dir_in, largest_packet_size, true); +} + +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc ) { + const unsigned ep_addr = ep_desc->bEndpointAddress; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned mps = tu_edpt_packet_size(ep_desc); + + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); + + pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; + pipe->buf = NULL; + pipe->length = 0; + pipe->remaining = 0; + + musb_regs_t* musb = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); + const uint8_t is_rx = 1 - dir_in; + musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[is_rx]; + + maxp_csr->maxp = mps; + maxp_csr->csrh |= MUSB_CSRH_ISO; +#if MUSB_CFG_SHARED_FIFO + if (dir_in) { + maxp_csr->csrh |= MUSB_CSRH_TX_MODE; + } +#endif + + // flush fifo + if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) { + maxp_csr->csrl = MUSB_CSRL_FLUSH_FIFO(is_rx); + } + +#if MUSB_CFG_DYNAMIC_FIFO + // fifo space is already allocated, keep the address and just change packet size + musb->fifo_size[is_rx] = hwfifo_byte2size(mps) | MUSB_FIFOSZ_DOUBLE_PACKET; +#endif + + musb->intren_ep[is_rx] |= TU_BIT(epn); + + if (ie) musb_dcd_int_enable(rhport); + + return true; +} void dcd_edpt_close_all(uint8_t rhport) { @@ -707,7 +768,7 @@ void dcd_edpt_close_all(uint8_t rhport) } maxp_csr->csrl = csrl; - fifo_reset(musb, i, 1-d); + hwfifo_reset(musb, i, 1-d); } } @@ -718,38 +779,6 @@ void dcd_edpt_close_all(uint8_t rhport) if (ie) musb_dcd_int_enable(rhport); } -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) -{ - // FIXME: we should implement iso_alloc() and iso_activate() - unsigned const epn = tu_edpt_number(ep_addr); - unsigned const dir_in = tu_edpt_dir(ep_addr); - musb_regs_t* musb = MUSB_REGS(rhport); - musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); - unsigned const ie = musb_dcd_get_int_enable(rhport); - musb_dcd_int_disable(rhport); - if (dir_in) { - musb->intr_txen &= ~TU_BIT(epn); - ep_csr->tx_maxp = 0; - ep_csr->tx_csrh = 0; - if (ep_csr->tx_csrl & MUSB_TXCSRL1_TXRDY) { - ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT | MUSB_TXCSRL1_FLUSH; - } else { - ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT; - } - } else { - musb->intr_rxen &= ~TU_BIT(epn); - ep_csr->rx_maxp = 0; - ep_csr->rx_csrh = 0; - if (ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY) { - ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT | MUSB_RXCSRL1_FLUSH; - } else { - ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT; - } - } - fifo_reset(musb, epn, dir_in); - if (ie) musb_dcd_int_enable(rhport); -} - // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { @@ -771,7 +800,8 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t return ret; } -// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c +// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack +// - optional, however, must be listed in usbd.c bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) { (void)rhport; diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index 680bebde7..d17e836ee 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -42,8 +42,8 @@ #error "Unsupported MCUs" #endif -#define MUSB_CFG_SHARED_FIFO 0 -#define MUSB_CFG_DYNAMIC_FIFO 1 +#define MUSB_CFG_SHARED_FIFO 0 +#define MUSB_CFG_DYNAMIC_FIFO 1 #define MUSB_CFG_DYNAMIC_FIFO_SIZE 4096 const uintptr_t MUSB_BASES[] = { USB0_BASE }; @@ -51,11 +51,6 @@ const uintptr_t MUSB_BASES[] = { USB0_BASE }; // Header supports both device and host modes. Only include what's necessary #if CFG_TUD_ENABLED -// Mapping of peripheral instances to port. Currently just 1. -static USB0_Type* const musb_periph_inst[] = { - USB0 -}; - // Mapping of IRQ numbers to port. Currently just 1. static const IRQn_Type musb_irqs[] = { USB0_IRQn @@ -87,142 +82,6 @@ static inline void musb_dcd_int_handler_enter(uint8_t rhport) { //Nothing to do for this part } -#if 0 -typedef struct { - uint_fast16_t beg; /* offset of including first element */ - uint_fast16_t end; /* offset of excluding the last element */ -} free_block_t; - -static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) { - free_block_t *cur = beg; - for (; cur < end && ((addr < cur->beg) || (cur->end <= addr)); ++cur) ; - return cur; -} - -static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) { - free_block_t *p = find_containing_block(blks, blks + num, addr); - TU_ASSERT(p != blks + num, -2); - if (p->beg == addr) { - /* Shrink block */ - p->beg = addr + size; - if (p->beg != p->end) return 0; - /* remove block */ - free_block_t *end = blks + num; - while (p + 1 < end) { - *p = *(p + 1); - ++p; - } - return -1; - } else { - /* Split into 2 blocks */ - free_block_t tmp = { - .beg = addr + size, - .end = p->end - }; - p->end = addr; - if (p->beg == p->end) { - if (tmp.beg != tmp.end) { - *p = tmp; - return 0; - } - /* remove block */ - free_block_t *end = blks + num; - while (p + 1 < end) { - *p = *(p + 1); - ++p; - } - return -1; - } - if (tmp.beg == tmp.end) return 0; - blks[num] = tmp; - return 1; - } -} - -static inline unsigned free_block_size(free_block_t const *blk) { - return blk->end - blk->beg; -} - -#if 0 -static inline void print_block_list(free_block_t const *blk, unsigned num) -{ - TU_LOG1("*************\r\n"); - for (unsigned i = 0; i < num; ++i) { - TU_LOG1(" Blk%u %u %u\r\n", i, blk->beg, blk->end); - ++blk; - } -} -#else -#define print_block_list(a,b) -#endif - -static unsigned find_free_memory(uint8_t rhport, uint_fast16_t size_in_log2_minus3) -{ - free_block_t free_blocks[2 * (TUP_DCD_ENDPOINT_MAX - 1)]; - unsigned num_blocks = 1; - - /* Initialize free memory block list */ - free_blocks[0].beg = 64 / 8; - free_blocks[0].end = (4 << 10) / 8; /* 4KiB / 8 bytes */ - for (int i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - uint_fast16_t addr; - int num; - musb_periph_inst[rhport]->EPIDX = i; - addr = musb_periph_inst[rhport]->TXFIFOADD; - if (addr) { - unsigned sz = musb_periph_inst[rhport]->TXFIFOSZ; - unsigned sft = (sz & USB_TXFIFOSZ_SIZE_M) + ((sz & USB_TXFIFOSZ_DPB) ? 1: 0); - num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); - TU_ASSERT(-2 < num, 0); - num_blocks += num; - print_block_list(free_blocks, num_blocks); - } - addr = musb_periph_inst[rhport]->RXFIFOADD; - if (addr) { - unsigned sz = musb_periph_inst[rhport]->RXFIFOSZ; - unsigned sft = (sz & USB_RXFIFOSZ_SIZE_M) + ((sz & USB_RXFIFOSZ_DPB) ? 1: 0); - num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); - TU_ASSERT(-2 < num, 0); - num_blocks += num; - print_block_list(free_blocks, num_blocks); - } - } - print_block_list(free_blocks, num_blocks); - - /* Find the best fit memory block */ - uint_fast16_t size_in_8byte_unit = 1 << size_in_log2_minus3; - free_block_t const *min = NULL; - uint_fast16_t min_sz = 0xFFFFu; - free_block_t const *end = &free_blocks[num_blocks]; - for (free_block_t const *cur = &free_blocks[0]; cur < end; ++cur) { - uint_fast16_t sz = free_block_size(cur); - if (sz < size_in_8byte_unit) continue; - if (size_in_8byte_unit == sz) return cur->beg; - if (sz < min_sz) min = cur; - } - TU_ASSERT(min, 0); - return min->beg; -} - - -static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) -{ - int size_in_log2_minus3 = 28 - TU_MIN(28, __CLZ((uint32_t)mps)); - if ((8u << size_in_log2_minus3) < mps) ++size_in_log2_minus3; - unsigned addr = find_free_memory(rhport, size_in_log2_minus3); - TU_ASSERT(addr,); - - musb_periph_inst[rhport]->EPIDX = epnum; - if (dir_in) { - musb_periph_inst[rhport]->TXFIFOADD = addr; - musb_periph_inst[rhport]->TXFIFOSZ = size_in_log2_minus3; - } else { - musb_periph_inst[rhport]->RXFIFOADD = addr; - musb_periph_inst[rhport]->RXFIFOSZ = size_in_log2_minus3; - } -} -#endif - #endif // CFG_TUD_ENABLED #ifdef __cplusplus diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index f8a66acce..4e448c0ed 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -338,6 +338,10 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // 0x13, 0x17: TX/RX CSRH #define MUSB_CSRH_DISABLE_DOUBLE_PACKET(_rx) (1u << 1) #define MUSB_CSRH_TX_MODE (1u << 5) // 1 = TX, 0 = RX. only relevant for SHARED FIFO +#define MUSB_CSRH_ISO (1u << 6) + +// 0x62, 0x63: TXFIFO_SZ, RXFIFO_SZ +#define MUSB_FIFOSZ_DOUBLE_PACKET (1u << 4) //***************************************************************************** @@ -417,58 +421,6 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ #define MUSB_CCONF_TXEDMA 0x0002 // TX Early DMA Enable #define MUSB_CCONF_RXEDMA 0x0001 // TX Early DMA Enable -//***************************************************************************** -// -// The following are defines for the bit fields in the MUSB_O_TXFIFOSZ register. -// -//***************************************************************************** -#define MUSB_TXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support -#define MUSB_TXFIFOSZ_SIZE_M 0x000F // Max Packet Size -#define MUSB_TXFIFOSZ_SIZE_8 0x0000 // 8 -#define MUSB_TXFIFOSZ_SIZE_16 0x0001 // 16 -#define MUSB_TXFIFOSZ_SIZE_32 0x0002 // 32 -#define MUSB_TXFIFOSZ_SIZE_64 0x0003 // 64 -#define MUSB_TXFIFOSZ_SIZE_128 0x0004 // 128 -#define MUSB_TXFIFOSZ_SIZE_256 0x0005 // 256 -#define MUSB_TXFIFOSZ_SIZE_512 0x0006 // 512 -#define MUSB_TXFIFOSZ_SIZE_1024 0x0007 // 1024 -#define MUSB_TXFIFOSZ_SIZE_2048 0x0008 // 2048 - -//***************************************************************************** -// -// The following are defines for the bit fields in the MUSB_O_RXFIFOSZ register. -// -//***************************************************************************** -#define MUSB_RXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support -#define MUSB_RXFIFOSZ_SIZE_M 0x000F // Max Packet Size -#define MUSB_RXFIFOSZ_SIZE_8 0x0000 // 8 -#define MUSB_RXFIFOSZ_SIZE_16 0x0001 // 16 -#define MUSB_RXFIFOSZ_SIZE_32 0x0002 // 32 -#define MUSB_RXFIFOSZ_SIZE_64 0x0003 // 64 -#define MUSB_RXFIFOSZ_SIZE_128 0x0004 // 128 -#define MUSB_RXFIFOSZ_SIZE_256 0x0005 // 256 -#define MUSB_RXFIFOSZ_SIZE_512 0x0006 // 512 -#define MUSB_RXFIFOSZ_SIZE_1024 0x0007 // 1024 -#define MUSB_RXFIFOSZ_SIZE_2048 0x0008 // 2048 - -//***************************************************************************** -// -// The following are defines for the bit fields in the MUSB_O_TXFIFOADD -// register. -// -//***************************************************************************** -#define MUSB_TXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address -#define MUSB_TXFIFOADD_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the MUSB_O_RXFIFOADD -// register. -// -//***************************************************************************** -#define MUSB_RXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address -#define MUSB_RXFIFOADD_ADDR_S 0 - //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_ULPIVBUSCTL -- cgit v1.3.1 From 0c9d7a21858d246dfaadb78122c27c6e4099109c Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 19 Aug 2024 12:38:45 +0700 Subject: add hwfifo_flush() --- src/portable/mentor/musb/dcd_musb.c | 72 ++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index dc2753ea6..a40b3dc07 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -81,11 +81,13 @@ typedef struct uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ } dcd_data_t; -/*------------------------------------------------------------------ - * INTERNAL OBJECT & FUNCTION DECLARATION - *------------------------------------------------------------------*/ static dcd_data_t _dcd; +//-------------------------------------------------------------------- +// HW FIFO Helper +// Note: Index register is already set by caller +//-------------------------------------------------------------------- + #if MUSB_CFG_DYNAMIC_FIFO // musb is configured to use dynamic FIFO sizing. @@ -97,24 +99,20 @@ static uint32_t alloced_fifo_bytes; // ffsize is log2(mps) - 3 (round up) TU_ATTR_ALWAYS_INLINE static inline uint8_t hwfifo_byte2size(uint16_t nbytes) { uint8_t ffsize = 28 - tu_min8(28, __builtin_clz(nbytes)); - // round up to the next power of 2 if ((8u << ffsize) < nbytes) { ++ffsize; } - return ffsize; } -// index register is already set -TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { +TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigned epnum, unsigned is_rx) { (void) epnum; - const uint8_t is_rx = 1 - dir_in; musb->fifo_size[is_rx] = 0; musb->fifo_addr[is_rx] = 0; } -// index register is already set -TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps, bool double_packet) { +TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned is_rx, unsigned mps, + bool double_packet) { (void) epnum; uint8_t ffsize = hwfifo_byte2size(mps); mps = 8 << ffsize; // round up to the next power of 2 @@ -125,8 +123,6 @@ TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsign } TU_ASSERT(alloced_fifo_bytes + mps <= MUSB_CFG_DYNAMIC_FIFO_SIZE); - const uint8_t is_rx = 1 - dir_in; - musb->fifo_addr[is_rx] = alloced_fifo_bytes / 8; musb->fifo_size[is_rx] = ffsize; @@ -136,20 +132,16 @@ TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsign #else -// index register is already set -TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { - (void) musb; (void) epnum; (void) dir_in; +TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigned epnum, unsigned is_rx) { + (void) musb; (void) epnum; (void) is_rx; // nothing to do for static FIFO } -// index register is already set -TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps, +TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned is_rx, unsigned mps, bool double_packet) { - (void) epnum; (void) dir_in; (void) mps; - + (void) epnum; (void) mps; if (!double_packet) { #if defined(TUP_USBIP_MUSB_ADI) - const uint8_t is_rx = 1 - dir_in; musb->indexed_csr.maxp_csr[is_rx].csrh |= MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); #else if (is_rx) { @@ -165,6 +157,19 @@ TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsign #endif +// Flush FIFO and clear data toggle +TU_ATTR_ALWAYS_INLINE static inline void hwfifo_flush(musb_regs_t* musb, unsigned epnum, unsigned is_rx, bool clear_dtog) { + (void) epnum; + const uint8_t csrl_dtog = clear_dtog ? MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx) : 0; + musb_ep_maxp_csr_t* maxp_csr = &musb->indexed_csr.maxp_csr[is_rx]; + // may need to flush twice for double packet + for (unsigned i=0; i<2; i++) { + if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) { + maxp_csr->csrl = MUSB_CSRL_FLUSH_FIFO(is_rx) | csrl_dtog; + } + } +} + static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; @@ -679,14 +684,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { } #endif - // flush and reset data toggle - uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx); - if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) { - csrl |= MUSB_CSRL_FLUSH_FIFO(is_rx); - } - maxp_csr->csrl = csrl; + hwfifo_flush(musb, epn, is_rx, true); - TU_ASSERT(hwfifo_config(musb, epn, dir_in, mps, false)); + TU_ASSERT(hwfifo_config(musb, epn, is_rx, mps, false)); musb->intren_ep[is_rx] |= TU_BIT(epn); return true; @@ -699,7 +699,7 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); const uint8_t is_rx = 1 - dir_in; ep_csr->maxp_csr[is_rx].csrh = 0; - return hwfifo_config(musb, epn, dir_in, largest_packet_size, true); + return hwfifo_config(musb, epn, is_rx, largest_packet_size, true); } bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc ) { @@ -729,10 +729,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc ) } #endif - // flush fifo - if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) { - maxp_csr->csrl = MUSB_CSRL_FLUSH_FIFO(is_rx); - } + hwfifo_flush(musb, epn, is_rx, true); #if MUSB_CFG_DYNAMIC_FIFO // fifo space is already allocated, keep the address and just change packet size @@ -758,17 +755,10 @@ void dcd_edpt_close_all(uint8_t rhport) musb_ep_csr_t* ep_csr = get_ep_csr(musb, i); for (unsigned d = 0; d < 2; d++) { musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[d]; + hwfifo_flush(musb, i, d, true); + hwfifo_reset(musb, i, d); maxp_csr->maxp = 0; maxp_csr->csrh = 0; - - // flush and reset data toggle - uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(d); - if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) { - csrl |= MUSB_CSRL_FLUSH_FIFO(d); - } - maxp_csr->csrl = csrl; - - hwfifo_reset(musb, i, 1-d); } } -- cgit v1.3.1 From 635bdc1fcea1d4d9972d4c9960a32250b0245186 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 19 Aug 2024 13:20:16 +0700 Subject: fix ci build --- src/device/dcd.h | 2 +- src/device/usbd.c | 1 - test/hil/rpi.json | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/device/dcd.h b/src/device/dcd.h index 66fae0802..d1d4e4897 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -181,7 +181,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) #else // Close an endpoint. -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr); +void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) TU_ATTR_WEAK; #endif diff --git a/src/device/usbd.c b/src/device/usbd.c index d6f69fc24..67faf0da7 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1424,7 +1424,6 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) { #else rhport = _usbd_rhport; - TU_ASSERT(dcd_edpt_close, /**/); TU_LOG_USBD(" CLOSING Endpoint: 0x%02X\r\n", ep_addr); uint8_t const epnum = tu_edpt_number(ep_addr); diff --git a/test/hil/rpi.json b/test/hil/rpi.json index a10fa76bd..e90e435d8 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -18,7 +18,7 @@ "name": "max32666fthr", "uid": "0C81464124010B20FF0A08CC2C", "flasher": "openocd_adi", - "flasher_sn": "040917023bffc88100000000000000000000000097969906", + "flasher_sn": "042217023bffc88100000000000000000000000097969906", "flasher_args": "-f interface/cmsis-dap.cfg -f target/max32665.cfg" }, { -- cgit v1.3.1 From 088486186f514578a02d6b6c7f39e0ad74f56118 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 19 Aug 2024 19:05:33 +0700 Subject: rename TUD_ENDPOINT_EXCLUSIVE_NUMBER to TUD_ENDPOINT_ONE_DIRECTION_ONLY --- examples/device/cdc_dual_ports/src/usb_descriptors.c | 2 +- examples/device/cdc_msc/src/usb_descriptors.c | 2 +- examples/device/cdc_msc_freertos/src/usb_descriptors.c | 2 +- examples/device/cdc_uac2/src/usb_descriptors.c | 2 +- .../device/dynamic_configuration/src/usb_descriptors.c | 2 +- examples/device/midi_test/src/usb_descriptors.c | 2 +- examples/device/msc_dual_lun/src/usb_descriptors.c | 2 +- examples/device/net_lwip_webserver/src/usb_descriptors.c | 2 +- examples/device/uac2_headset/src/usb_descriptors.c | 2 +- examples/device/uac2_speaker_fb/src/usb_descriptors.c | 2 +- examples/device/video_capture/src/tusb_config.h | 2 +- examples/device/video_capture/src/usb_descriptors.c | 2 ++ examples/device/webusb_serial/src/usb_descriptors.c | 2 +- src/common/tusb_mcu.h | 16 ++++++++-------- 14 files changed, 22 insertions(+), 20 deletions(-) diff --git a/examples/device/cdc_dual_ports/src/usb_descriptors.c b/examples/device/cdc_dual_ports/src/usb_descriptors.c index ca4fe279b..7776eb958 100644 --- a/examples/device/cdc_dual_ports/src/usb_descriptors.c +++ b/examples/device/cdc_dual_ports/src/usb_descriptors.c @@ -109,7 +109,7 @@ enum #define EPNUM_CDC_1_OUT 0x05 #define EPNUM_CDC_1_IN 0x84 -#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) +#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_0_NOTIF 0x81 diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c index 4789f5a9b..4b6b88041 100644 --- a/examples/device/cdc_msc/src/usb_descriptors.c +++ b/examples/device/cdc_msc/src/usb_descriptors.c @@ -103,7 +103,7 @@ enum { #define EPNUM_MSC_OUT 0x05 #define EPNUM_MSC_IN 0x84 -#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) +#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 diff --git a/examples/device/cdc_msc_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_freertos/src/usb_descriptors.c index 7f9338753..405a57fe4 100644 --- a/examples/device/cdc_msc_freertos/src/usb_descriptors.c +++ b/examples/device/cdc_msc_freertos/src/usb_descriptors.c @@ -103,7 +103,7 @@ enum { #define EPNUM_MSC_OUT 0x05 #define EPNUM_MSC_IN 0x84 -#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) +#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 diff --git a/examples/device/cdc_uac2/src/usb_descriptors.c b/examples/device/cdc_uac2/src/usb_descriptors.c index 6384f722a..9f7255d8a 100644 --- a/examples/device/cdc_uac2/src/usb_descriptors.c +++ b/examples/device/cdc_uac2/src/usb_descriptors.c @@ -97,7 +97,7 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 -#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) +#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_AUDIO_IN 0x01 diff --git a/examples/device/dynamic_configuration/src/usb_descriptors.c b/examples/device/dynamic_configuration/src/usb_descriptors.c index 7be3d7da5..0a2049288 100644 --- a/examples/device/dynamic_configuration/src/usb_descriptors.c +++ b/examples/device/dynamic_configuration/src/usb_descriptors.c @@ -132,7 +132,7 @@ enum #define EPNUM_1_MSC_OUT 0x02 #define EPNUM_1_MSC_IN 0x82 -#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) +#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_0_CDC_NOTIF 0x81 diff --git a/examples/device/midi_test/src/usb_descriptors.c b/examples/device/midi_test/src/usb_descriptors.c index 3511f7eba..3870eaaf0 100644 --- a/examples/device/midi_test/src/usb_descriptors.c +++ b/examples/device/midi_test/src/usb_descriptors.c @@ -93,7 +93,7 @@ enum #define EPNUM_MIDI_OUT 0x02 #define EPNUM_MIDI_IN 0x81 -#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) +#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_MIDI_OUT 0x01 diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c index bc2f2577c..efb9a966d 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -91,7 +91,7 @@ enum #define EPNUM_MSC_OUT 0x02 #define EPNUM_MSC_IN 0x81 -#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) +#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_MSC_OUT 0x01 diff --git a/examples/device/net_lwip_webserver/src/usb_descriptors.c b/examples/device/net_lwip_webserver/src/usb_descriptors.c index 2a3061162..d061f5076 100644 --- a/examples/device/net_lwip_webserver/src/usb_descriptors.c +++ b/examples/device/net_lwip_webserver/src/usb_descriptors.c @@ -120,7 +120,7 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_NET_OUT 0x02 #define EPNUM_NET_IN 0x81 -#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) +#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_NET_NOTIF 0x81 diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c index e8dc5ec15..bc9160d5e 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -97,7 +97,7 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_AUDIO_OUT 0x08 #define EPNUM_AUDIO_INT 0x01 -#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) +#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_AUDIO_IN 0x01 diff --git a/examples/device/uac2_speaker_fb/src/usb_descriptors.c b/examples/device/uac2_speaker_fb/src/usb_descriptors.c index aadeb7e8a..ee1b92225 100644 --- a/examples/device/uac2_speaker_fb/src/usb_descriptors.c +++ b/examples/device/uac2_speaker_fb/src/usb_descriptors.c @@ -131,7 +131,7 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf) #define EPNUM_AUDIO_OUT 0x08 #define EPNUM_DEBUG 0x01 -#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) +#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_AUDIO_FB 0x01 diff --git a/examples/device/video_capture/src/tusb_config.h b/examples/device/video_capture/src/tusb_config.h index 21483a2da..3a6daa3d3 100644 --- a/examples/device/video_capture/src/tusb_config.h +++ b/examples/device/video_capture/src/tusb_config.h @@ -106,7 +106,7 @@ #define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE 256 // use bulk endpoint for streaming interface -#define CFG_TUD_VIDEO_STREAMING_BULK 1 + #define CFG_TUD_VIDEO_STREAMING_BULK 0 //#define CFG_EXAMPLE_VIDEO_READONLY //#define CFG_EXAMPLE_VIDEO_DISABLE_MJPEG diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index 5011bee18..b3e19b0f0 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -118,6 +118,8 @@ enum { #elif TU_CHECK_MCU(OPT_MCU_NRF5X) // nRF5x ISO can only be endpoint 8 #define EPNUM_VIDEO_IN (CFG_TUD_VIDEO_STREAMING_BULK ? 0x81 : 0x88) +#elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002) + #define EPNUM_VIDEO_IN 0x81 #else #define EPNUM_VIDEO_IN 0x81 #endif diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c index 2ff6d9ced..2b69a5b56 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.c +++ b/examples/device/webusb_serial/src/usb_descriptors.c @@ -104,7 +104,7 @@ enum #define EPNUM_VENDOR_OUT 0x05 #define EPNUM_VENDOR_IN 0x84 -#elif defined(TUD_ENDPOINT_EXCLUSIVE_NUMBER) +#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index e86f55c1d..52debf079 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -138,21 +138,21 @@ #elif TU_CHECK_MCU(OPT_MCU_SAMG) #define TUP_DCD_ENDPOINT_MAX 6 - #define TUD_ENDPOINT_EXCLUSIVE_NUMBER + #define TUD_ENDPOINT_ONE_DIRECTION_ONLY #elif TU_CHECK_MCU(OPT_MCU_SAMX7X) #define TUP_DCD_ENDPOINT_MAX 10 #define TUP_RHPORT_HIGHSPEED 1 - #define TUD_ENDPOINT_EXCLUSIVE_NUMBER + #define TUD_ENDPOINT_ONE_DIRECTION_ONLY #elif TU_CHECK_MCU(OPT_MCU_PIC32MZ) #define TUP_DCD_ENDPOINT_MAX 8 - #define TUD_ENDPOINT_EXCLUSIVE_NUMBER + #define TUD_ENDPOINT_ONE_DIRECTION_ONLY #elif TU_CHECK_MCU(OPT_MCU_PIC32MX, OPT_MCU_PIC32MM, OPT_MCU_PIC32MK) || \ TU_CHECK_MCU(OPT_MCU_PIC24, OPT_MCU_DSPIC33) #define TUP_DCD_ENDPOINT_MAX 16 - #define TUD_ENDPOINT_EXCLUSIVE_NUMBER + #define TUD_ENDPOINT_ONE_DIRECTION_ONLY //--------------------------------------------------------------------+ // ST @@ -299,7 +299,7 @@ #elif TU_CHECK_MCU(OPT_MCU_CXD56) #define TUP_DCD_ENDPOINT_MAX 7 #define TUP_RHPORT_HIGHSPEED 1 - #define TUD_ENDPOINT_EXCLUSIVE_NUMBER + #define TUD_ENDPOINT_ONE_DIRECTION_ONLY //--------------------------------------------------------------------+ // TI @@ -400,12 +400,12 @@ #elif TU_CHECK_MCU(OPT_MCU_FT90X) #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_RHPORT_HIGHSPEED 1 - #define TUD_ENDPOINT_EXCLUSIVE_NUMBER + #define TUD_ENDPOINT_ONE_DIRECTION_ONLY #elif TU_CHECK_MCU(OPT_MCU_FT93X) #define TUP_DCD_ENDPOINT_MAX 16 #define TUP_RHPORT_HIGHSPEED 1 - #define TUD_ENDPOINT_EXCLUSIVE_NUMBER + #define TUD_ENDPOINT_ONE_DIRECTION_ONLY //--------------------------------------------------------------------+ // Allwinner @@ -480,7 +480,7 @@ #define TUP_USBIP_MUSB_ADI #define TUP_DCD_ENDPOINT_MAX 12 #define TUP_RHPORT_HIGHSPEED 1 - #define TUD_ENDPOINT_EXCLUSIVE_NUMBER + #define TUD_ENDPOINT_ONE_DIRECTION_ONLY #endif -- cgit v1.3.1 From 215832397b1593e2df5609f92c9346c133a03774 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 19 Aug 2024 19:07:47 +0700 Subject: update doc, re-enable metro m7 for hil, only build make windows/macos on PR --- .github/workflows/build.yml | 5 +- README.rst | 4 +- docs/reference/supported.rst | 277 +++++++++++++++++++++---------------------- test/hil/rpi.json | 15 ++- 4 files changed, 149 insertions(+), 152 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fde9400a7..e4204ca3d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,7 +66,7 @@ jobs: build-system: 'cmake' toolchain: ${{ matrix.toolchain }} build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} - one-per-family: ${{ github.event_name != 'pull_request' }} + one-per-family: ${{ github.event_name == 'push' }} # --------------------------------------- # Build CMake arm-gcc @@ -103,12 +103,13 @@ jobs: build-system: 'make' toolchain: ${{ matrix.toolchain }} build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} - one-per-family: ${{ github.event_name != 'pull_request' }} + one-per-family: ${{ github.event_name == 'push' }} # --------------------------------------- # Build Make on Windows/MacOS # --------------------------------------- make-os: + if: github.event_name == 'pull_request' uses: ./.github/workflows/build_util.yml strategy: fail-fast: false diff --git a/README.rst b/README.rst index 422f23271..6dd0e2714 100644 --- a/README.rst +++ b/README.rst @@ -109,7 +109,9 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l +==============+============================================================+ | Allwinner | F1C100s/F1C200s | +--------------+------------------------------------------------------------+ -| Analog | MAX3421E (usb host shield) | +| Analog | max32: 650, 666, 690. max78002 | +| | | +| | max3421e (host) | +--------------+------------------------------------------------------------+ | Brigetek | FT90x | +--------------+------------------------------------------------------------+ diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index edb6b69ca..2bfa1b8d0 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -5,147 +5,142 @@ Supported Devices Supported MCUs ============== -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| Manufacturer | Family | Device | Host | Highspeed | Driver | Note | -+==============+=======================+========+======+===========+===================+==============+ -| Allwinner | F1C100s/F1C200s | ✔ | | ✔ | sunxi | musb variant | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| Analog | MAX3421E | | ✔ | ✖ | max3421 | via SPI | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| Brigetek | FT90x | ✔ | | ✔ | ft9xx | | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| Broadcom | BCM2711, BCM2837 | ✔ | | ✔ | dwc2 | | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| Espressif | ESP32 S2, S3 | ✔ | | ✖ | dwc2 or esp32sx | | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| Infineon | XMC4500 | ✔ | | ✖ | dwc2 | | -+--------------+-----+-----------------+--------+------+-----------+-------------------+--------------+ -| MicroChip | SAM | D11, D21 | ✔ | | ✖ | samd | | -| | +-----------------+--------+------+-----------+-------------------+--------------+ -| | | D51, E5x | ✔ | | ✖ | samd | | -| | +-----------------+--------+------+-----------+-------------------+--------------+ -| | | G55 | ✔ | | ✖ | samg | | -| | +-----------------+--------+------+-----------+-------------------+--------------+ -| | | L21, L22 | ✔ | | ✖ | samd | | -| | +-----------------+--------+------+-----------+-------------------+--------------+ -| | | E70,S70,V70,V71 | ✔ | | ✔ | samx7x | | -| +-----+-----------------+--------+------+-----------+-------------------+--------------+ -| | PIC | 24 | ✔ | | | pic | ci_fs variant| -| | +-----------------+--------+------+-----------+-------------------+--------------+ -| | | 32 mm, mk, mx | ✔ | | | pic | ci_fs variant| -| | +-----------------+--------+------+-----------+-------------------+--------------+ -| | | dsPIC33 | ✔ | | | pic | ci_fs variant| -| | +-----------------+--------+------+-----------+-------------------+--------------+ -| | | 32mz | ✔ | | | pic32mz | musb variant | -+--------------+-----+-----------------+--------+------+-----------+-------------------+--------------+ -| Mind Montion | mm32 | ✔ | | ✖ | mm32f327x_otg | ci_fs variant| -+--------------+-----+-----------------+--------+------+-----------+-------------------+--------------+ -| NordicSemi | nRF52833, nRF52840 | ✔ | ✖ | ✖ | nrf5x | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | nRF5340 | ✔ | ✖ | ✖ | nrf5x | | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| Nuvoton | NUC120 | ✔ | ✖ | ✖ | nuc120 | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | NUC121/NUC125 | ✔ | ✖ | ✖ | nuc121 | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | NUC126 | ✔ | ✖ | ✖ | nuc121 | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | NUC505 | ✔ | | ✔ | nuc505 | | -+--------------+---------+-------------+--------+------+-----------+-------------------+--------------+ -| NXP | iMXRT | RT10xx | ✔ | ✔ | ✔ | ci_hs | | -| | +-------------+--------+------+-----------+-------------------+--------------+ -| | | RT11xx | ✔ | ✔ | ✔ | ci_hs | | -| +---------+-------------+--------+------+-----------+-------------------+--------------+ -| | Kinetis | KL | ✔ | âš  | ✖ | ci_fs, khci | | -| | +-------------+--------+------+-----------+-------------------+--------------+ -| | | K32L2 | ✔ | | ✖ | khci | ci_fs variant| -| +---------+-------------+--------+------+-----------+-------------------+--------------+ -| | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | | -| | +-------------+--------+------+-----------+-------------------+--------------+ -| | | 17, 40 | ✔ | âš  | ✖ | lpc17_40 | | -| | +-------------+--------+------+-----------+-------------------+--------------+ -| | | 18, 43 | ✔ | ✔ | ✔ | ci_hs | | -| | +-------------+--------+------+-----------+-------------------+--------------+ -| | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | | -| | +-------------+--------+------+-----------+-------------------+--------------+ -| | | 54 | ✔ | | ✔ | lpc_ip3511 | | -| | +-------------+--------+------+-----------+-------------------+--------------+ -| | | 55 | ✔ | | ✔ | lpc_ip3511 | | -| +---------+-------------+--------+------+-----------+-------------------+--------------+ -| | MCX | N9 | ✔ | | ✔ | ci_fs, ci_hs | | -+--------------+---------+-------------+--------+------+-----------+-------------------+--------------+ -| Raspberry Pi | RP2040 | ✔ | ✔ | ✖ | rp2040, pio_usb | | -+--------------+-----+-----------------+--------+------+-----------+-------------------+--------------+ -| Renesas | RX | 63N, 65N, 72N | ✔ | ✔ | ✖ | rusb2 | | -| +-----+-----------------+--------+------+-----------+-------------------+--------------+ -| | RA | 4M1, 4M3, 6M1 | ✔ | ✔ | ✖ | rusb2 | | -| | +-----------------+--------+------+-----------+-------------------+--------------+ -| | | 6M5 | ✔ | ✔ | ✔ | rusb2 | | -+--------------+-----+-----------------+--------+------+-----------+-------------------+--------------+ -| Silabs | EFM32GG12 | ✔ | | ✖ | dwc2 | | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| Sony | CXD56 | ✔ | ✖ | ✔ | cxd56 | | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| ST STM32 | F0 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +----+------------------+--------+------+-----------+-------------------+--------------+ -| | F1 | 102, 103 | ✔ | ✖ | ✖ | stm32_fsdev | | -| | +------------------+--------+------+-----------+-------------------+--------------+ -| | | 105, 107 | ✔ | | ✖ | dwc2 | | -| +----+------------------+--------+------+-----------+-------------------+--------------+ -| | F2 | ✔ | | ✔ | dwc2 | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | F3 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | F4 | ✔ | | ✔ | dwc2 | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | F7 | ✔ | | ✔ | dwc2 | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | G0 | ✔ | | ✖ | stm32_fsdev | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | H5 | ✔ | | ✖ | stm32_fsdev | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | H7 | ✔ | | ✔ | dwc2 | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | L0 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | L1 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +----+------------------+--------+------+-----------+-------------------+--------------+ -| | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | | -| | +------------------+--------+------+-----------+-------------------+--------------+ -| | | 4x5, 4x6 | ✔ | | ✖ | dwc2 | | -| +----+------------------+--------+------+-----------+-------------------+--------------+ -| | L4+ | ✔ | | ✖ | dwc2 | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | L5 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +----+------------------+--------+------+-----------+-------------------+--------------+ -| | U5 | 535, 545 | ✔ | | ✖ | stm32_fsdev | | -| | +------------------+--------+------+-----------+-------------------+--------------+ -| | | 575, 585 | ✔ | | ✖ | dwc2 | | -| | +------------------+--------+------+-----------+-------------------+--------------+ -| | | 59x,5Ax,5Fx,5Gx | ✔ | | ✔ | dwc2 | | -| +----+------------------+--------+------+-----------+-------------------+--------------+ -| | WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | MSP432E4 | ✔ | | ✖ | musb | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | TM4C123 | ✔ | | ✖ | musb | | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| WCH | CH32F20x | ✔ | | ✔ | ch32f205 | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | CH32V20x | ✔ | | ✖ | ch32v20x | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | CH32V307 | ✔ | | ✔ | ch32v307 | | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ ++--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ +| Manufacturer | Family | Device | Host | Highspeed | Driver | Note | ++==============+=============================+========+======+===========+===================+===================+ +| Allwinner | F1C100s/F1C200s | ✔ | | ✔ | sunxi | musb variant | ++--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ +| Analog | MAX3421E | | ✔ | ✖ | max3421 | via SPI | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | MAX32 650, 666, 690, | ✔ | | ✔ | musb | 1-dir ep | +| | MAX78002 | | | | | | ++--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ +| Brigetek | FT90x | ✔ | | ✔ | ft9xx | 1-dir ep | ++--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ +| Broadcom | BCM2711, BCM2837 | ✔ | | ✔ | dwc2 | | ++--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ +| Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | | ++--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ +| Espressif | ESP32 S2, S3 | ✔ | | ✖ | dwc2 or esp32sx | | ++--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ +| GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | | ++--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ +| Infineon | XMC4500 | ✔ | | ✖ | dwc2 | | ++--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+ +| MicroChip | SAM | D11, D21, L21, L22 | ✔ | | ✖ | samd | | +| | +-----------------------+--------+------+-----------+-------------------+-------------------+ +| | | D51, E5x | ✔ | | ✖ | samd | | +| | +-----------------------+--------+------+-----------+-------------------+-------------------+ +| | | G55 | ✔ | | ✖ | samg | 1-dir ep | +| | +-----------------------+--------+------+-----------+-------------------+-------------------+ +| | | E70,S70,V70,V71 | ✔ | | ✔ | samx7x | 1-dir ep | +| +-----+-----------------------+--------+------+-----------+-------------------+-------------------+ +| | PIC | 24 | ✔ | | | pic | ci_fs variant | +| | +-----------------------+--------+------+-----------+-------------------+-------------------+ +| | | 32 mm, mk, mx | ✔ | | | pic | ci_fs variant | +| | +-----------------------+--------+------+-----------+-------------------+-------------------+ +| | | dsPIC33 | ✔ | | | pic | ci_fs variant | +| | +-----------------------+--------+------+-----------+-------------------+-------------------+ +| | | 32mz | ✔ | | | pic32mz | musb variant | ++--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+ +| Mind Montion | mm32 | ✔ | | ✖ | mm32f327x_otg | ci_fs variant | ++--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+ +| NordicSemi | nRF 52833, 52840, 5340 | ✔ | ✖ | ✖ | nrf5x | only ep8 is ISO | ++--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ +| Nuvoton | NUC120 | ✔ | ✖ | ✖ | nuc120 | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | NUC121/NUC125 | ✔ | ✖ | ✖ | nuc121 | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | NUC126 | ✔ | ✖ | ✖ | nuc121 | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | NUC505 | ✔ | | ✔ | nuc505 | | ++--------------+---------+-------------------+--------+------+-----------+-------------------+-------------------+ +| NXP | iMXRT | RT 10xx, 11xx | ✔ | ✔ | ✔ | ci_hs | | +| +---------+-------------------+--------+------+-----------+-------------------+-------------------+ +| | Kinetis | KL | ✔ | âš  | ✖ | ci_fs, khci | | +| | +-------------------+--------+------+-----------+-------------------+-------------------+ +| | | K32L2 | ✔ | | ✖ | khci | ci_fs variant | +| +---------+-------------------+--------+------+-----------+-------------------+-------------------+ +| | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | | +| | +-------------------+--------+------+-----------+-------------------+-------------------+ +| | | 17, 40 | ✔ | âš  | ✖ | lpc17_40 | | +| | +-------------------+--------+------+-----------+-------------------+-------------------+ +| | | 18, 43 | ✔ | ✔ | ✔ | ci_hs | | +| | +-------------------+--------+------+-----------+-------------------+-------------------+ +| | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | | +| | +-------------------+--------+------+-----------+-------------------+-------------------+ +| | | 54, 55 | ✔ | | ✔ | lpc_ip3511 | | +| +---------+-------------------+--------+------+-----------+-------------------+-------------------+ +| | MCX | N9 | ✔ | | ✔ | ci_fs, ci_hs | | ++--------------+---------+-------------------+--------+------+-----------+-------------------+-------------------+ +| Raspberry Pi | RP2040, RP2350 | ✔ | ✔ | ✖ | rp2040, pio_usb | | ++--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+ +| Renesas | RX | 63N, 65N, 72N | ✔ | ✔ | ✖ | rusb2 | | +| +-----+-----------------------+--------+------+-----------+-------------------+-------------------+ +| | RA | 4M1, 4M3, 6M1 | ✔ | ✔ | ✖ | rusb2 | | +| | +-----------------------+--------+------+-----------+-------------------+-------------------+ +| | | 6M5 | ✔ | ✔ | ✔ | rusb2 | | ++--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+ +| Silabs | EFM32GG12 | ✔ | | ✖ | dwc2 | | ++--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ +| Sony | CXD56 | ✔ | ✖ | ✔ | cxd56 | | ++--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ +| ST STM32 | F0 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +----+------------------------+--------+------+-----------+-------------------+-------------------+ +| | F1 | 102, 103 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | +------------------------+--------+------+-----------+-------------------+-------------------+ +| | | 105, 107 | ✔ | | ✖ | dwc2 | | +| +----+------------------------+--------+------+-----------+-------------------+-------------------+ +| | F2 | ✔ | | ✔ | dwc2 | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | F3 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | F4 | ✔ | | ✔ | dwc2 | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | F7 | ✔ | | ✔ | dwc2 | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | G0 | ✔ | | ✖ | stm32_fsdev | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | H5 | ✔ | | ✖ | stm32_fsdev | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | H7 | ✔ | | ✔ | dwc2 | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | L0 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | L1 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +----+------------------------+--------+------+-----------+-------------------+-------------------+ +| | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | +------------------------+--------+------+-----------+-------------------+-------------------+ +| | | 4x5, 4x6 | ✔ | | ✖ | dwc2 | | +| +----+------------------------+--------+------+-----------+-------------------+-------------------+ +| | L4+ | ✔ | | ✖ | dwc2 | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | L5 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +----+------------------------+--------+------+-----------+-------------------+-------------------+ +| | U5 | 535, 545 | ✔ | | ✖ | stm32_fsdev | | +| | +------------------------+--------+------+-----------+-------------------+-------------------+ +| | | 575, 585 | ✔ | | ✖ | dwc2 | | +| | +------------------------+--------+------+-----------+-------------------+-------------------+ +| | | 59x,5Ax,5Fx,5Gx | ✔ | | ✔ | dwc2 | | +| +----+------------------------+--------+------+-----------+-------------------+-------------------+ +| | WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | | ++--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ +| TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | MSP432E4 | ✔ | | ✖ | musb | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | TM4C123 | ✔ | | ✖ | musb | | ++--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ +| ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | ++--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ +| WCH | CH32F20x | ✔ | | ✔ | ch32f205 | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | CH32V20x | ✔ | | ✖ | ch32v20x | | +| +-----------------------------+--------+------+-----------+-------------------+-------------------+ +| | CH32V307 | ✔ | | ✔ | ch32v307 | | ++--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ Table Legend diff --git a/test/hil/rpi.json b/test/hil/rpi.json index e90e435d8..b87b80300 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -14,6 +14,13 @@ "flasher_sn": "E6614C311B597D32", "flasher_args": "-f interface/cmsis-dap.cfg -f target/atsame5x.cfg -c \"adapter speed 5000\"" }, + { + "name": "metro_m7_1011", + "uid": "9CE8715DD71137363E00005002004200", + "flasher": "jlink", + "flasher_sn": "000611000000", + "flasher_args": "-device MIMXRT1011xxx5A" + }, { "name": "max32666fthr", "uid": "0C81464124010B20FF0A08CC2C", @@ -60,14 +67,6 @@ } ], "boards-skip": [ - { - "name": "metro_m7_1011", - "uid": "9CE8715DD71137363E00005002004200", - "flasher": "jlink", - "flasher_sn": "000611000000", - "flasher_args": "-device MIMXRT1011xxx5A", - "comment": "not running reliably in bulk with other boards, probably power, flashing etc .." - }, { "name": "nanoch32v203", "uid": "CDAB277B0FBC03E339E339E3", -- cgit v1.3.1 From ea4f9ceb58f0aa6acc86bbe3083596a98b5355fd Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 19 Aug 2024 20:08:55 +0700 Subject: remove weak from dcd_edpt_close() for port without TUP_DCD_EDPT_ISO_ALLOC --- src/device/dcd.h | 2 +- src/portable/microchip/samg/dcd_samg.c | 5 +++++ src/portable/nxp/lpc17_40/dcd_lpc17_40.c | 5 +++++ src/portable/template/dcd_template.c | 16 ++++++++++++++++ src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 5 +++++ src/portable/valentyusb/eptri/dcd_eptri.c | 5 +++++ 6 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/device/dcd.h b/src/device/dcd.h index d1d4e4897..3ef5188fc 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -181,7 +181,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) #else // Close an endpoint. -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) TU_ATTR_WEAK; +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr); #endif diff --git a/src/portable/microchip/samg/dcd_samg.c b/src/portable/microchip/samg/dcd_samg.c index e3fa51e31..a15431937 100644 --- a/src/portable/microchip/samg/dcd_samg.c +++ b/src/portable/microchip/samg/dcd_samg.c @@ -277,6 +277,11 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) return true; } +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; (void) ep_addr; + // TODO implement dcd_edpt_close() +} + void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index b880c2870..75b29faf3 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -335,6 +335,11 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) return true; } +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; (void) ep_addr; + // TODO implement dcd_edpt_close() +} + void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; diff --git a/src/portable/template/dcd_template.c b/src/portable/template/dcd_template.c index 12d610bd6..25ee507c1 100644 --- a/src/portable/template/dcd_template.c +++ b/src/portable/template/dcd_template.c @@ -102,6 +102,22 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) return false; } +// Allocate packet buffer used by ISO endpoints +// Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void) rhport; + (void) ep_addr; + (void) largest_packet_size; + return false; +} + +// Configure and enable an ISO endpoint according to descriptor +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { + (void) rhport; + (void) desc_ep; + return false; +} + void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 8005f5f7b..6b60bc657 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -332,6 +332,11 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) return true; } +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; (void) ep_addr; + // TODO implement dcd_edpt_close() +} + void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; diff --git a/src/portable/valentyusb/eptri/dcd_eptri.c b/src/portable/valentyusb/eptri/dcd_eptri.c index 58628a8bb..8f40e3349 100644 --- a/src/portable/valentyusb/eptri/dcd_eptri.c +++ b/src/portable/valentyusb/eptri/dcd_eptri.c @@ -436,6 +436,11 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) return true; } +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; (void) ep_addr; + // TODO implement dcd_edpt_close() +} + void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; -- cgit v1.3.1 From 0541598d07fd57e4ad0067abe85c4c7a71b3756a Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 19 Aug 2024 20:09:32 +0700 Subject: mimxrt1015_evk does not work reliably in hil pool (like metro m7). --- test/hil/hil_test.py | 6 +++--- test/hil/rpi.json | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index e5900c616..09c30bf52 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -436,11 +436,11 @@ def main(): else: config_boards = [e for e in config['boards'] if e['name'] in boards] - err_count_list = 0 + err_count_list = [] with Pool(processes=os.cpu_count()) as pool: err_count_list = pool.map(test_board, config_boards) - - sys.exit(sum(err_count_list)) + err_count = sum(err_count_list) + sys.exit(err_count) if __name__ == '__main__': diff --git a/test/hil/rpi.json b/test/hil/rpi.json index b87b80300..49d2d8286 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -14,13 +14,6 @@ "flasher_sn": "E6614C311B597D32", "flasher_args": "-f interface/cmsis-dap.cfg -f target/atsame5x.cfg -c \"adapter speed 5000\"" }, - { - "name": "metro_m7_1011", - "uid": "9CE8715DD71137363E00005002004200", - "flasher": "jlink", - "flasher_sn": "000611000000", - "flasher_args": "-device MIMXRT1011xxx5A" - }, { "name": "max32666fthr", "uid": "0C81464124010B20FF0A08CC2C", @@ -67,6 +60,13 @@ } ], "boards-skip": [ + { + "name": "mimxrt1015_evk", + "uid": "DC28F865D2111D228D00B0543A70463C", + "flasher": "jlink", + "flasher_sn": "000726284213", + "flasher_args": "-device MIMXRT1015DAF5A" + }, { "name": "nanoch32v203", "uid": "CDAB277B0FBC03E339E339E3", -- cgit v1.3.1 From 61187008285d70d700e30e5f11636240ae4845d0 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Wed, 21 Aug 2024 19:09:37 +0700 Subject: update circle ci to build make (#2769) * update build.py script to work with circleci * build make with circle ci * build vm for esp only * nrf imxrt with large resource * nrf imxrt with large resource * remove 2 of nrf boards --- .circleci/config.yml | 46 +++++- .circleci/config2.yml | 162 ++++++++++++++----- .github/workflows/build.yml | 46 +----- .github/workflows/build_util.yml | 7 +- .github/workflows/ci_set_matrix.py | 9 +- hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake | 5 - hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.h | 52 ------- hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.mk | 15 -- .../nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld | 13 -- hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake | 4 - hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.h | 52 ------- hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.mk | 7 - tools/build.py | 171 +++++++++++---------- tools/build_utils.py | 35 ----- 14 files changed, 274 insertions(+), 350 deletions(-) delete mode 100644 hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake delete mode 100644 hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.h delete mode 100644 hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.mk delete mode 100644 hw/bsp/nrf/boards/nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld delete mode 100644 hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake delete mode 100644 hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.h delete mode 100644 hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.mk diff --git a/.circleci/config.yml b/.circleci/config.yml index 4d541a595..8769926b1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,16 +18,52 @@ jobs: MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py) echo "MATRIX_JSON=$MATRIX_JSON" - TOOLCHAIN_LIST=("arm-clang" "arm-gcc") - for toolchain in "${TOOLCHAIN_LIST[@]}"; do + BUILDSYSTEM_TOOLCHAIN=( + "cmake arm-clang" + "make aarch64-gcc" + "make arm-gcc" + "make msp430-gcc" + "make riscv-gcc" + # "make rx-gcc" llvm-gcc-renesas.com seems to be down + "cmake esp-idf" + ) + + RESOURCE_LARGE='["nrf", "imxrt"]' + + for e in "${BUILDSYSTEM_TOOLCHAIN[@]}"; do + e_arr=($e) + build_system="${e_arr[0]}" + toolchain="${e_arr[1]}" FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\".family") - echo "${toolchain}_FAMILY=$FAMILY" - echo " - build:" >> .circleci/config2.yml + echo "FAMILY_${toolchain}=$FAMILY" + + # FAMILY_LARGE = FAMILY - RESOURCE_LARGE + # Separate large from medium+ resources + FAMILY_LARGE=$(jq -n --argjson family "$FAMILY" --argjson resource "$RESOURCE_LARGE" '$family | map(select(IN($resource[])))') + FAMILY=$(jq -n --argjson family "$FAMILY" --argjson resource "$RESOURCE_LARGE" '$family | map(select(IN($resource[]) | not))') + + if [[ $toolchain == esp-idf ]]; then + echo " - build-vm:" >> .circleci/config2.yml + else + echo " - build:" >> .circleci/config2.yml + fi echo " matrix:" >> .circleci/config2.yml echo " parameters:" >> .circleci/config2.yml + echo " build-system: ['$build_system']" >> .circleci/config2.yml echo " toolchain: ['$toolchain']" >> .circleci/config2.yml - echo " build-system: ['cmake']" >> .circleci/config2.yml echo " family: $FAMILY" >> .circleci/config2.yml + #echo " resource_class: ['medium+']" >> .circleci/config2.yml + + # add large resources + if [ "$(echo $FAMILY_LARGE | jq 'length')" -gt 0 ]; then + echo " - build:" >> .circleci/config2.yml + echo " matrix:" >> .circleci/config2.yml + echo " parameters:" >> .circleci/config2.yml + echo " build-system: ['$build_system']" >> .circleci/config2.yml + echo " toolchain: ['$toolchain']" >> .circleci/config2.yml + echo " family: $FAMILY_LARGE" >> .circleci/config2.yml + echo " resource_class: ['large']" >> .circleci/config2.yml + fi done - continuation/continue: diff --git a/.circleci/config2.yml b/.circleci/config2.yml index ea7fccaff..cd844c33f 100644 --- a/.circleci/config2.yml +++ b/.circleci/config2.yml @@ -5,44 +5,124 @@ commands: parameters: toolchain: type: string + steps: - run: - name: Install Toolchain + name: Set toolchain url and key command: | TOOLCHAIN_JSON='{ + "aarch64-gcc": "https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz", "arm-clang": "https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-17.0.1/LLVMEmbeddedToolchainForArm-17.0.1-Linux-x86_64.tar.xz", - "arm-gcc": "https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v12.3.1-1.1/xpack-arm-none-eabi-gcc-12.3.1-1.1-linux-x64.tar.gz" + "arm-gcc": "https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v12.3.1-1.1/xpack-arm-none-eabi-gcc-12.3.1-1.1-linux-x64.tar.gz", + "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", + "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz", + "rx-gcc": "https://llvm-gcc-renesas.com/downloads/get.php?f=rx/8.3.0.202004-gnurx/gcc-8.3.0.202004-GNURX-ELF.run" }' toolchain_url=$(echo $TOOLCHAIN_JSON | jq -r '.["<< parameters.toolchain >>"]') - echo "toolchain_url=$toolchain_url" - # download and extract toolchain - mkdir -p ~/cache/<< parameters.toolchain >> - wget $toolchain_url -O toolchain.tar.gz - tar -C ~/cache/<< parameters.toolchain >> -xaf toolchain.tar.gz + # only cache if not a github link + if [[ $toolchain_url != "https://github.com"* ]]; then + echo "<< parameters.toolchain >>-$toolchain_url" > toolchain_key + fi + echo "export toolchain_url=$toolchain_url" >> $BASH_ENV + + - restore_cache: + name: Restore Toolchain Cache + key: deps-{{ checksum "toolchain_key" }} + paths: + - ~/cache/<< parameters.toolchain >> + + - run: + name: Install Toolchain + command: | + # download if folder does not exist (not cached) + if [ ! -d ~/cache/<< parameters.toolchain >> ]; then + mkdir -p ~/cache/<< parameters.toolchain >> + wget --progress=dot:giga $toolchain_url -O toolchain.tar.gz + if [[ << parameters.toolchain >> == rx-gcc ]]; then + mv toolchain.tar.gz toolchain.run + chmod +x toolchain.run + ./toolchain.run -p ~/cache/<< parameters.toolchain >>/gnurx -y + else + tar -C ~/cache/<< parameters.toolchain >> -xaf toolchain.tar.gz + fi + fi # Add toolchain to PATH echo "export PATH=$PATH:`echo ~/cache/<< parameters.toolchain >>/*/bin`" >> $BASH_ENV - get-deps: + - save_cache: + name: Save Toolchain Cache + key: deps-{{ checksum "toolchain_key" }} + paths: + - ~/cache/<< parameters.toolchain >> + + build: parameters: + build-system: + type: string + toolchain: + type: string family: type: string + steps: + - checkout + - when: + condition: + not: + equal: [esp-idf, << parameters.toolchain >>] + steps: + - setup-toolchain: + toolchain: << parameters.toolchain >> + - run: name: Get Dependencies command: | python tools/get_deps.py << parameters.family >> + # Install ninja if cmake build system + if [ << parameters.build-system >> == "cmake" ]; then + NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-linux.zip + wget $NINJA_URL -O ninja-linux.zip + unzip ninja-linux.zip -d ~/bin + fi + # Install Pico SDK if [ << parameters.family >> == "rp2040" ]; then git clone --depth 1 https://github.com/raspberrypi/pico-sdk.git ~/pico-sdk echo "export PICO_SDK_PATH=~/pico-sdk" >> $BASH_ENV fi + - run: + name: Build + command: | + if [ << parameters.toolchain >> == esp-idf ]; then + docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python tools/build.py << parameters.family >> + else + # Only build one board per family for non PRs i.e commit to master + ONE_PER_FAMILY="" + if [ -z "$CIRCLE_PULL_REQUEST" ]; then + ONE_PER_FAMILY="--one-per-family" + fi + + # Toolchain option default is gcc + if [ << parameters.toolchain >> == arm-clang ]; then + TOOLCHAIN_OPTION="--toolchain clang" + elif [ << parameters.toolchain >> == arm-gcc ]; then + TOOLCHAIN_OPTION="--toolchain gcc" + fi + + python tools/build.py $ONE_PER_FAMILY -s << parameters.build-system >> $TOOLCHAIN_OPTION << parameters.family >> + fi + jobs: + # Build using docker build: parameters: + resource_class: + type: string + default: medium+ build-system: type: string toolchain: @@ -52,40 +132,36 @@ jobs: docker: - image: cimg/base:current - resource_class: medium+ + resource_class: << parameters.resource_class >> + steps: - - checkout - - when: - condition: << parameters.build-system >> == 'cmake' - steps: - - run: - name: Install Ninja - command: | - # Install Ninja - NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-linux.zip - wget $NINJA_URL -O ninja-linux.zip - unzip ninja-linux.zip -d ~/bin - - setup-toolchain: + - build: + build-system: << parameters.build-system >> toolchain: << parameters.toolchain >> - - get-deps: family: << parameters.family >> - - run: - name: Build - command: | - # Only build one board per family for non PRs i.e commit to master - ONE_PER_FAMILY="" - if [ -z "$CIRCLE_PULL_REQUEST" ]; then - ONE_PER_FAMILY="--one-per-family" - fi - # Toolchain option default is gcc - if [ "<< parameters.toolchain >>" == "arm-clang" ]; then - TOOLCHAIN_OPTION="--toolchain clang" - elif [ "<< parameters.toolchain >>" == "arm-gcc" ]; then - TOOLCHAIN_OPTION="--toolchain gcc" - fi + # Build using VM + build-vm: + parameters: + resource_class: + type: string + default: large + build-system: + type: string + toolchain: + type: string + family: + type: string - python tools/build.py $ONE_PER_FAMILY -s << parameters.build-system >> $TOOLCHAIN_OPTION << parameters.family >> + machine: + image: ubuntu-2404:current + resource_class: << parameters.resource_class >> + + steps: + - build: + build-system: << parameters.build-system >> + toolchain: << parameters.toolchain >> + family: << parameters.family >> workflows: build: @@ -93,6 +169,14 @@ workflows: # - build: # matrix: # parameters: -# toolchain: ['arm-clang'] +# toolchain: [ 'arm-gcc' ] +# build-system: [ 'cmake' ] +# family: [ 'nrf' ] +# resource_class: ['large'] +# - build-vm: +# matrix: +# parameters: +# toolchain: ['esp-idf'] # build-system: ['cmake'] -# family: ['imxrt'] +# family: ['-bespressif_kaluga_1'] +# resource_class: ['large'] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e4204ca3d..6ca9885f8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,7 +51,6 @@ jobs: # Build CMake # --------------------------------------- cmake: - # if: false needs: set-matrix uses: ./.github/workflows/build_util.yml strategy: @@ -60,6 +59,7 @@ jobs: toolchain: # - 'arm-clang' is built by circle-ci in PR - 'aarch64-gcc' + - 'arm-gcc' - 'msp430-gcc' - 'riscv-gcc' with: @@ -69,41 +69,28 @@ jobs: one-per-family: ${{ github.event_name == 'push' }} # --------------------------------------- - # Build CMake arm-gcc - # only build with push, for PR: all board is built by circle-ci - # --------------------------------------- - cmake-arm-gcc: - if: github.event_name == 'push' - needs: set-matrix - uses: ./.github/workflows/build_util.yml - with: - build-system: 'cmake' - toolchain: 'arm-gcc' - build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)['arm-gcc'].family) }} - one-per-family: true - - # --------------------------------------- - # Build Make + # Build Make (built by circle-ci in PR, only build on push here) # --------------------------------------- make: - # if: false + if: github.event_name == 'push' needs: set-matrix uses: ./.github/workflows/build_util.yml strategy: fail-fast: false matrix: toolchain: - # 'arm-clang' would be built by circle-ci - - 'aarch64-gcc' + # 'arm-clang' - 'arm-gcc' + - 'aarch64-gcc' - 'msp430-gcc' - 'riscv-gcc' - 'rx-gcc' + - 'esp-idf' # buid-system is ignored with: build-system: 'make' toolchain: ${{ matrix.toolchain }} build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} - one-per-family: ${{ github.event_name == 'push' }} + one-per-family: true # --------------------------------------- # Build Make on Windows/MacOS @@ -122,29 +109,10 @@ jobs: build-args: '["stm32h7"]' one-per-family: true - # --------------------------------------- - # Build Espressif - # --------------------------------------- - espressif: - # if: false - uses: ./.github/workflows/build_util.yml - strategy: - fail-fast: false - matrix: - board: - - 'espressif_kaluga_1' - - 'espressif_s3_devkitm' - with: - build-system: 'cmake' - toolchain: 'esp-idf' - toolchain_version: 'v5.1.1' - build-args: '["-b${{ matrix.board }}"]' - # --------------------------------------- # Build IAR on HFP self-hosted # --------------------------------------- arm-iar: - # if: false if: github.repository_owner == 'hathach' needs: set-matrix runs-on: [self-hosted, Linux, X64, hifiphile] diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index e983f06d1..ff98aef2d 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -9,9 +9,6 @@ on: toolchain: required: true type: string - toolchain_version: - required: false - type: string build-args: required: true type: string @@ -40,7 +37,7 @@ jobs: uses: ./.github/actions/setup_toolchain with: toolchain: ${{ inputs.toolchain }} - toolchain_version: ${{ inputs.toolchain_version }} + toolchain_version: 'v5.1.1' - name: Get Dependencies uses: ./.github/actions/get_deps @@ -60,7 +57,7 @@ jobs: - name: Build run: | if [ "${{ inputs.toolchain }}" == "esp-idf" ]; then - docker run --rm -v $PWD:/project -w /project espressif/idf:${{ inputs.toolchain_version }} python3 tools/build.py ${{ matrix.arg }} + docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python tools/build.py ${{ matrix.arg }} else python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} fi diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index c9698c934..4da26bfea 100644 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -6,6 +6,7 @@ toolchain_list = [ "arm-clang", "arm-iar", "arm-gcc", + "esp-idf", "msp430-gcc", "riscv-gcc", "rx-gcc" @@ -31,15 +32,19 @@ family_list = { "ra": ["arm-gcc"], "rp2040": ["arm-gcc"], "rx": ["rx-gcc"], - "samd11 samd21 saml2x": ["arm-gcc", "arm-clang"], + "samd11 saml2x": ["arm-gcc", "arm-clang"], + "samd21": ["arm-gcc", "arm-clang"], "samd5x_e5x samg": ["arm-gcc", "arm-clang"], "stm32f0 stm32f1 stm32f2 stm32f3": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f4": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f7": ["arm-gcc", "arm-clang", "arm-iar"], "stm32g0 stm32g4 stm32h5": ["arm-gcc", "arm-clang", "arm-iar"], "stm32h7": ["arm-gcc", "arm-clang", "arm-iar"], - "stm32l0 stm32l4 stm32u5 stm32wb": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32l0 stm32l4": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32u5 stm32wb": ["arm-gcc", "arm-clang", "arm-iar"], "xmc4000": ["arm-gcc"], + "-bespressif_kaluga_1": ["esp-idf"], + "-bespressif_s3_devkitm": ["esp-idf"], } diff --git a/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake b/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake deleted file mode 100644 index ffa5932c1..000000000 --- a/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(MCU_VARIANT nrf52840) -set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/nrf52840_mdk_dongle.ld) - -function(update_board TARGET) -endfunction() diff --git a/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.h b/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.h deleted file mode 100644 index 072cb2714..000000000 --- a/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#define _PINNUM(port, pin) ((port)*32 + (pin)) - -// LED -#define LED_PIN _PINNUM(0, 23) -#define LED_STATE_ON 0 - -// Button -#define BUTTON_PIN _PINNUM(0, 18) -#define BUTTON_STATE_ACTIVE 0 - -// UART -#define UART_RX_PIN 2 -#define UART_TX_PIN 3 - -#ifdef __cplusplus - } -#endif - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.mk b/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.mk deleted file mode 100644 index f25ec8f34..000000000 --- a/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.mk +++ /dev/null @@ -1,15 +0,0 @@ -MCU_VARIANT = nrf52840 -CFLAGS += -DNRF52840_XXAA - -LD_FILE = $(BOARD_PATH)/$(BOARD).ld - -# flash using Nordic nrfutil (pip3 install nrfutil) -# make BOARD=nrf52840_mdk_dongle SERIAL=/dev/ttyACM0 all flash -NRFUTIL = nrfutil - -$(BUILD)/$(PROJECT).zip: $(BUILD)/$(PROJECT).hex - $(NRFUTIL) pkg generate --hw-version 52 --sd-req 0x0000 --debug-mode --application $^ $@ - -flash: $(BUILD)/$(PROJECT).zip - @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) - $(NRFUTIL) dfu usb-serial --package $^ -p $(SERIAL) -b 115200 diff --git a/hw/bsp/nrf/boards/nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld b/hw/bsp/nrf/boards/nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld deleted file mode 100644 index a6bc6dcfe..000000000 --- a/hw/bsp/nrf/boards/nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld +++ /dev/null @@ -1,13 +0,0 @@ -/* Linker script to configure memory regions. */ - -SEARCH_DIR(.) -/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0xE0000-0x1000 - RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 0x3fff8 -} - - -INCLUDE "nrf_common.ld" diff --git a/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake b/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake deleted file mode 100644 index cc370aac8..000000000 --- a/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake +++ /dev/null @@ -1,4 +0,0 @@ -set(MCU_VARIANT nrf52840) - -function(update_board TARGET) -endfunction() diff --git a/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.h b/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.h deleted file mode 100644 index bc203f073..000000000 --- a/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#define _PINNUM(port, pin) ((port)*32 + (pin)) - -// LED -#define LED_PIN _PINNUM(1, 13) -#define LED_STATE_ON 0 - -// Button -#define BUTTON_PIN _PINNUM(0, 15) -#define BUTTON_STATE_ACTIVE 0 - -// UART -#define UART_RX_PIN 25 -#define UART_TX_PIN 24 - -#ifdef __cplusplus - } -#endif - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.mk b/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.mk deleted file mode 100644 index be2ed3314..000000000 --- a/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.mk +++ /dev/null @@ -1,7 +0,0 @@ -MCU_VARIANT = nrf52840 -CFLAGS += -DNRF52840_XXAA - -LD_FILE = hw/mcu/nordic/nrfx/mdk/nrf52840_xxaa.ld - -# flash using jlink -flash: flash-jlink diff --git a/tools/build.py b/tools/build.py index b937a7342..f9ae68231 100644 --- a/tools/build.py +++ b/tools/build.py @@ -9,19 +9,29 @@ from multiprocessing import Pool import build_utils -SUCCEEDED = "\033[32msucceeded\033[0m" -FAILED = "\033[31mfailed\033[0m" +STATUS_OK = "\033[32mOK\033[0m" +STATUS_FAILED = "\033[31mFailed\033[0m" +STATUS_SKIPPED = "\033[33mSkipped\033[0m" -build_separator = '-' * 106 +RET_OK = 0 +RET_FAILED = 1 +RET_SKIPPED = 2 +build_format = '| {:30} | {:40} | {:16} | {:5} |' +build_separator = '-' * 95 +build_status = [STATUS_OK, STATUS_FAILED, STATUS_SKIPPED] + +# ----------------------------- +# Helper +# ----------------------------- def run_cmd(cmd): #print(cmd) r = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - title = 'command error' + title = f'Command Error: {cmd}' if r.returncode != 0: # print build output if failed - if os.getenv('CI'): + if os.getenv('GITHUB_ACTIONS'): print(f"::group::{title}") print(r.stdout.decode("utf-8")) print(f"::endgroup::") @@ -30,6 +40,7 @@ def run_cmd(cmd): print(r.stdout.decode("utf-8")) return r + def find_family(board): bsp_dir = Path("hw/bsp") for family_dir in bsp_dir.iterdir(): @@ -56,70 +67,91 @@ def get_examples(family): return all_examples -def build_board_cmake(board, toolchain): - start_time = time.monotonic() - ret = [0, 0, 0] +def print_build_result(board, example, status, duration): + if isinstance(duration, (int, float)): + duration = "{:.2f}s".format(duration) + print(build_format.format(board, example, build_status[status], duration)) +# ----------------------------- +# CMake +# ----------------------------- +def cmake_board(board, toolchain): + ret = [0, 0, 0] + start_time = time.monotonic() build_dir = f"cmake-build/cmake-build-{board}" family = find_family(board) if family == 'espressif': # for espressif, we have to build example individually all_examples = get_examples(family) for example in all_examples: - r = run_cmd(f'cmake examples/{example} -B {build_dir}/{example} -G "Ninja" -DBOARD={board} -DMAX3421_HOST=1') - if r.returncode == 0: - r = run_cmd(f'cmake --build {build_dir}/{example}') - if r.returncode == 0: - ret[0] += 1 - else: - ret[1] += 1 + rcmd = run_cmd(f'cmake examples/{example} -B {build_dir}/{example} -G "Ninja" -DBOARD={board} -DMAX3421_HOST=1') + if rcmd.returncode == 0: + rcmd = run_cmd(f'cmake --build {build_dir}/{example}') + ret[0 if rcmd.returncode == 0 else 1] += 1 else: - r = run_cmd(f'cmake examples -B {build_dir} -G "Ninja" -DBOARD={board} -DCMAKE_BUILD_TYPE=MinSizeRel -DTOOLCHAIN={toolchain}') - if r.returncode == 0: - r = run_cmd(f"cmake --build {build_dir}") - if r.returncode == 0: - ret[0] += 1 - else: - ret[1] += 1 + rcmd = run_cmd(f'cmake examples -B {build_dir} -G "Ninja" -DBOARD={board} -DCMAKE_BUILD_TYPE=MinSizeRel -DTOOLCHAIN={toolchain}') + if rcmd.returncode == 0: + rcmd = run_cmd(f"cmake --build {build_dir}") + ret[0 if rcmd.returncode == 0 else 1] += 1 - duration = time.monotonic() - start_time + example = 'all' + print_build_result(board, example, 0 if ret[1] == 0 else 1, time.monotonic() - start_time) + return ret - if ret[1] == 0: - status = SUCCEEDED + +# ----------------------------- +# Make +# ----------------------------- +def make_one_example(example, board, make_option): + # Check if board is skipped + if build_utils.skip_example(example, board): + print_build_result(board, example, 2, '-') + r = 2 else: - status = FAILED + start_time = time.monotonic() + # skip -j for circleci + if not os.getenv('CIRCLECI'): + make_option += ' -j' + make_cmd = f"make -C examples/{example} BOARD={board} {make_option}" + # run_cmd(f"{make_cmd} clean") + build_result = run_cmd(f"{make_cmd} all") + r = 0 if build_result.returncode == 0 else 1 + print_build_result(board, example, r, time.monotonic() - start_time) - flash_size = "-" - sram_size = "-" - example = 'all' - title = build_utils.build_format.format(example, board, status, "{:.2f}s".format(duration), flash_size, sram_size) - print(title) + ret = [0, 0, 0] + ret[r] = 1 return ret -def build_board_make_all_examples(board, toolchain, all_examples): +def make_board(board, toolchain): + print(build_separator) + all_examples = get_examples(find_family(board)) start_time = time.monotonic() ret = [0, 0, 0] - with Pool(processes=os.cpu_count()) as pool: pool_args = list((map(lambda e, b=board, o=f"TOOLCHAIN={toolchain}": [e, b, o], all_examples))) - r = pool.starmap(build_utils.build_example, pool_args) + r = pool.starmap(make_one_example, pool_args) # sum all element of same index (column sum) - rsum = list(map(sum, list(zip(*r)))) - ret[0] += rsum[0] - ret[1] += rsum[1] - ret[2] += rsum[2] - duration = time.monotonic() - start_time - if ret[1] == 0: - status = SUCCEEDED - else: - status = FAILED - - flash_size = "-" - sram_size = "-" + ret = list(map(sum, list(zip(*r)))) example = 'all' - title = build_utils.build_format.format(example, board, status, "{:.2f}s".format(duration), flash_size, sram_size) - print(title) + print_build_result(board, example, 0 if ret[1] == 0 else 1, time.monotonic() - start_time) + return ret + + +# ----------------------------- +# Build Family +# ----------------------------- +def build_boards_list(boards, toolchain, build_system): + ret = [0, 0, 0] + for b in boards: + r = [0, 0, 0] + if build_system == 'cmake': + r = cmake_board(b, toolchain) + elif build_system == 'make': + r = make_board(b, toolchain) + ret[0] += r[0] + ret[1] += r[1] + ret[2] += r[2] return ret @@ -131,7 +163,6 @@ def build_family(family, toolchain, build_system, one_per_family, boards): all_boards.sort() ret = [0, 0, 0] - # If only-one flag is set, select one random board if one_per_family: for b in boards: @@ -140,21 +171,13 @@ def build_family(family, toolchain, build_system, one_per_family, boards): return ret all_boards = [random.choice(all_boards)] - # success, failed, skipped - all_examples = get_examples(family) - for board in all_boards: - r = [0, 0, 0] - if build_system == 'cmake': - r = build_board_cmake(board, toolchain) - elif build_system == 'make': - r = build_board_make_all_examples(board, toolchain, all_examples) - ret[0] += r[0] - ret[1] += r[1] - ret[2] += r[2] - + ret = build_boards_list(all_boards, toolchain, build_system) return ret +# ----------------------------- +# Main +# ----------------------------- def main(): parser = argparse.ArgumentParser() parser.add_argument('families', nargs='*', default=[], help='Families to build') @@ -175,7 +198,7 @@ def main(): return 1 print(build_separator) - print(build_utils.build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) + print(build_format.format('Board', 'Example', '\033[39mResult\033[0m', 'Time')) total_time = time.monotonic() result = [0, 0, 0] @@ -189,28 +212,22 @@ def main(): all_families = list(families) all_families.sort() - # succeeded, failed + # succeeded, failed, skipped for f in all_families: - fret = build_family(f, toolchain, build_system, one_per_family, boards) - result[0] += fret[0] - result[1] += fret[1] - result[2] += fret[2] - - # build boards - for b in boards: - r = [0, 0, 0] - if build_system == 'cmake': - r = build_board_cmake(b, toolchain) - elif build_system == 'make': - all_examples = get_examples(find_family(b)) - r = build_board_make_all_examples(b, toolchain, all_examples) + r = build_family(f, toolchain, build_system, one_per_family, boards) result[0] += r[0] result[1] += r[1] result[2] += r[2] + # build boards + r = build_boards_list(boards, toolchain, build_system) + result[0] += r[0] + result[1] += r[1] + result[2] += r[2] + total_time = time.monotonic() - total_time print(build_separator) - print(f"Build Summary: {result[0]} {SUCCEEDED}, {result[1]} {FAILED} and took {total_time:.2f}s") + print(f"Build Summary: {result[0]} {STATUS_OK}, {result[1]} {STATUS_FAILED} and took {total_time:.2f}s") print(build_separator) return result[1] diff --git a/tools/build_utils.py b/tools/build_utils.py index 32aca95dd..5f88db8a2 100644 --- a/tools/build_utils.py +++ b/tools/build_utils.py @@ -92,38 +92,3 @@ def build_size(make_cmd): return (flash_size, sram_size) return (0, 0) - - -def build_example(example, board, make_option): - start_time = time.monotonic() - flash_size = "-" - sram_size = "-" - - # succeeded, failed, skipped - ret = [0, 0, 0] - - make_cmd = f"make -j -C examples/{example} BOARD={board} {make_option}" - - # Check if board is skipped - if skip_example(example, board): - status = SKIPPED - ret[2] = 1 - print(build_format.format(example, board, status, '-', flash_size, sram_size)) - else: - build_result = subprocess.run(f"{make_cmd} all", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - if build_result.returncode == 0: - status = SUCCEEDED - ret[0] = 1 - (flash_size, sram_size) = build_size(make_cmd) - else: - status = FAILED - ret[1] = 1 - - build_duration = time.monotonic() - start_time - print(build_format.format(example, board, status, "{:.2f}s".format(build_duration), flash_size, sram_size)) - - if build_result.returncode != 0: - print(build_result.stdout.decode("utf-8")) - - return ret -- cgit v1.3.1 From 858ad66c9316250876dad533e47513b7def915d1 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Thu, 22 Aug 2024 12:37:11 +0700 Subject: circleci tweaks (#2770) * skip circleci build on master push * change max32666 probe to jlink, max32625pico is not reliable enough --- .circleci/config.yml | 4 ++++ .circleci/config2.yml | 8 +------- hw/bsp/max32690/family.cmake | 15 +-------------- test/hil/rpi.json | 13 ++++++++++--- 4 files changed, 16 insertions(+), 24 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8769926b1..5136d6331 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -71,5 +71,9 @@ jobs: workflows: set-matrix: + # Only build PR here, Push will be built by github action. + when: + and: + - not: << pipeline.git.branch.is_default >> jobs: - set-matrix diff --git a/.circleci/config2.yml b/.circleci/config2.yml index cd844c33f..70b5c60ac 100644 --- a/.circleci/config2.yml +++ b/.circleci/config2.yml @@ -100,12 +100,6 @@ commands: if [ << parameters.toolchain >> == esp-idf ]; then docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python tools/build.py << parameters.family >> else - # Only build one board per family for non PRs i.e commit to master - ONE_PER_FAMILY="" - if [ -z "$CIRCLE_PULL_REQUEST" ]; then - ONE_PER_FAMILY="--one-per-family" - fi - # Toolchain option default is gcc if [ << parameters.toolchain >> == arm-clang ]; then TOOLCHAIN_OPTION="--toolchain clang" @@ -113,7 +107,7 @@ commands: TOOLCHAIN_OPTION="--toolchain gcc" fi - python tools/build.py $ONE_PER_FAMILY -s << parameters.build-system >> $TOOLCHAIN_OPTION << parameters.family >> + python tools/build.py -s << parameters.build-system >> $TOOLCHAIN_OPTION << parameters.family >> fi jobs: diff --git a/hw/bsp/max32690/family.cmake b/hw/bsp/max32690/family.cmake index 736ca8eac..96dcfedff 100644 --- a/hw/bsp/max32690/family.cmake +++ b/hw/bsp/max32690/family.cmake @@ -148,18 +148,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_jlink(${TARGET}) - family_flash_msdk(${TARGET}) -endfunction() - -# Add flash msdk target -function(family_flash_msdk TARGET) - set(MAXIM_PATH "$ENV{MAXIM_PATH}") - - add_custom_target(${TARGET}-msdk - DEPENDS ${TARGET} - COMMAND ${MAXIM_PATH}/Tools/OpenOCD/openocd -s ${MAXIM_PATH}/Tools/OpenOCD/scripts - -f interface/cmsis-dap.cfg -f target/max32690.cfg - -c "program $ verify; init; reset; exit" - VERBATIM - ) + family_flash_openocd_adi(${TARGET}) endfunction() diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 49d2d8286..8eaca2621 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -17,9 +17,9 @@ { "name": "max32666fthr", "uid": "0C81464124010B20FF0A08CC2C", - "flasher": "openocd_adi", - "flasher_sn": "042217023bffc88100000000000000000000000097969906", - "flasher_args": "-f interface/cmsis-dap.cfg -f target/max32665.cfg" + "flasher": "jlink", + "flasher_sn": "000801011822", + "flasher_args": "-device max32666" }, { "name": "lpcxpresso11u37", @@ -83,6 +83,13 @@ "flasher": "esptool", "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", "flasher_args": "-b 921600" + }, + { + "name": "max32666fthr", + "uid": "0C81464124010B20FF0A08CC2C", + "flasher": "openocd_adi", + "flasher_sn": "042217023bffc88100000000000000000000000097969906", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/max32665.cfg" } ] } -- cgit v1.3.1 From 0db42aac71a6fb2a821a034ee29d2587638d309a Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Aug 2024 18:06:48 +0700 Subject: add hil support for dual host_info_to_cdc replace itsybitsy m4 by metro m4 + max3421e --- examples/dual/host_info_to_device_cdc/src/main.c | 26 ++++--- .../samd5x_e5x/boards/metro_m4_express/board.cmake | 3 + test/hil/hil_test.py | 89 ++++++++++++++-------- test/hil/rpi.json | 25 ++++-- 4 files changed, 95 insertions(+), 48 deletions(-) diff --git a/examples/dual/host_info_to_device_cdc/src/main.c b/examples/dual/host_info_to_device_cdc/src/main.c index 5be531098..443cc4674 100644 --- a/examples/dual/host_info_to_device_cdc/src/main.c +++ b/examples/dual/host_info_to_device_cdc/src/main.c @@ -24,7 +24,7 @@ */ /* Host example will get device descriptors of attached devices and print it out via device cdc as follows: - * Device 1: ID 046d:c52f + * Device 1: ID 046d:c52f SN 11223344 Device Descriptor: bLength 18 bDescriptorType 1 @@ -147,7 +147,21 @@ void print_device_info(uint8_t daddr) { return; } - cdc_printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct); + // Get String descriptor using Sync API + uint16_t serial[64]; + uint16_t buf[128]; + + cdc_printf("Device %u: ID %04x:%04x SN ", daddr, desc_device.idVendor, desc_device.idProduct); + xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, serial, sizeof(serial)); + if (XFER_RESULT_SUCCESS != xfer_result) { + serial[0] = 'n'; + serial[1] = '/'; + serial[2] = 'a'; + serial[3] = 0; + } + print_utf16(serial, TU_ARRAY_SIZE(serial)); + tud_cdc_write_str("\r\n"); + cdc_printf("Device Descriptor:\r\n"); cdc_printf(" bLength %u\r\n" , desc_device.bLength); cdc_printf(" bDescriptorType %u\r\n" , desc_device.bDescriptorType); @@ -160,9 +174,6 @@ void print_device_info(uint8_t daddr) { cdc_printf(" idProduct 0x%04x\r\n" , desc_device.idProduct); cdc_printf(" bcdDevice %04x\r\n" , desc_device.bcdDevice); - // Get String descriptor using Sync API - uint16_t buf[128]; - cdc_printf(" iManufacturer %u " , desc_device.iManufacturer); xfer_result = tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf)); if (XFER_RESULT_SUCCESS == xfer_result ) { @@ -178,10 +189,7 @@ void print_device_info(uint8_t daddr) { tud_cdc_write_str("\r\n"); cdc_printf(" iSerialNumber %u " , desc_device.iSerialNumber); - xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf)); - if (XFER_RESULT_SUCCESS == xfer_result) { - print_utf16(buf, TU_ARRAY_SIZE(buf)); - } + tud_cdc_write_str((char*)serial); // serial is already to UTF-8 tud_cdc_write_str("\r\n"); cdc_printf(" bNumConfigurations %u\r\n" , desc_device.bNumConfigurations); diff --git a/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.cmake b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.cmake index 86d12ca24..ebc32b1f7 100644 --- a/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.cmake +++ b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.cmake @@ -3,6 +3,9 @@ set(SAM_FAMILY samd51) set(JLINK_DEVICE ATSAMD51J19) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) +# force max3421e for testing with hardware-in-the-loop +set(MAX3421_HOST 1) + function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD51J19A__ diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 09c30bf52..5a4799cfb 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -27,6 +27,7 @@ import argparse import os +import re import sys import time import serial @@ -212,14 +213,39 @@ def flash_uniflash(board, firmware): # ------------------------------------------------------------- -# Tests +# Tests: dual # ------------------------------------------------------------- -def test_board_test(board): + +def test_dual_host_info_to_device_cdc(board): + uid = board['uid'] + declared_devs = [f'{d["vid_pid"]}_{d["serial"]}' for d in board['tests']['dual_attached']] + + port = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 0) + ser = open_serial_dev(port) + # read from cdc, first line should contain vid/pid and serial + data = ser.read(1000) + lines = data.decode('utf-8').splitlines() + enum_dev_sn = [] + for l in lines: + vid_pid_sn = re.search(r'ID ([0-9a-fA-F]+):([0-9a-fA-F]+) SN (\w+)', l) + if vid_pid_sn: + print(f'\r\n {l} ', end='') + enum_dev_sn.append(f'{vid_pid_sn.group(1)}_{vid_pid_sn.group(2)}_{vid_pid_sn.group(3)}') + + assert(set(declared_devs) == set(enum_dev_sn)), \ + f'Enumerated devices {enum_dev_sn} not match with declared {declared_devs}' + return 0 + + +# ------------------------------------------------------------- +# Tests: device +# ------------------------------------------------------------- +def test_device_board_test(board): # Dummy test pass -def test_cdc_dual_ports(board): +def test_device_cdc_dual_ports(board): uid = board['uid'] port1 = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 0) port2 = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 2) @@ -241,7 +267,7 @@ def test_cdc_dual_ports(board): assert ser2.read(100) == str2.upper(), 'Port2 wrong data' -def test_cdc_msc(board): +def test_device_cdc_msc(board): uid = board['uid'] # Echo test port = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 0) @@ -262,11 +288,11 @@ issue at github.com/hathach/tinyusb" assert data == readme, 'MSC wrong data' -def test_cdc_msc_freertos(board): - test_cdc_msc(board) +def test_device_cdc_msc_freertos(board): + test_device_cdc_msc(board) -def test_dfu(board): +def test_device_dfu(board): uid = board['uid'] # Wait device enum @@ -308,7 +334,7 @@ def test_dfu(board): os.remove(f_dfu1) -def test_dfu_runtime(board): +def test_device_dfu_runtime(board): uid = board['uid'] # Wait device enum @@ -325,7 +351,7 @@ def test_dfu_runtime(board): assert timeout, 'Device not available' -def test_hid_boot_interface(board): +def test_device_hid_boot_interface(board): uid = board['uid'] kbd = get_hid_dev(uid, 'TinyUSB', 'TinyUSB_Device', 'event-kbd') mouse1 = get_hid_dev(uid, 'TinyUSB', 'TinyUSB_Device', 'if01-event-mouse') @@ -341,7 +367,7 @@ def test_hid_boot_interface(board): assert timeout, 'HID device not available' -def test_hid_composite_freertos(id): +def test_device_hid_composite_freertos(id): # TODO implement later pass @@ -351,13 +377,15 @@ def test_hid_composite_freertos(id): # ------------------------------------------------------------- # all possible tests: board_test is added last to disable board's usb all_tests = [ - 'cdc_dual_ports', - 'cdc_msc', - 'dfu', - 'cdc_msc_freertos', # dont test 2 cdc_msc next to each other, since they have same vid/pid. Can be confused by host - 'dfu_runtime', - 'hid_boot_interface', - 'board_test' + 'device/cdc_dual_ports', + 'device/cdc_msc', + 'device/dfu', + 'device/cdc_msc_freertos', # don't test 2 cdc_msc next to each other + 'device/dfu_runtime', + 'device/hid_boot_interface', + + 'dual/host_info_to_device_cdc', + 'device/board_test' ] @@ -366,23 +394,23 @@ def test_board(board): flasher = board['flasher'].lower() # default to all tests - if 'tests' in board: - test_list = board['tests'] + ['board_test'] - else: - test_list = list(all_tests) + test_list = list(all_tests) - # remove skip_tests - if 'tests_skip' in board: - for skip in board['tests_skip']: - if skip in test_list: - test_list.remove(skip) + if 'tests' in board: + board_tests = board['tests'] + if 'only' in board_tests: + test_list = board_tests['only'] + ['device/board_test'] + if 'skip' in board_tests: + for skip in board_tests['skip']: + if skip in test_list: + test_list.remove(skip) err_count = 0 for test in test_list: - fw_dir = f'cmake-build/cmake-build-{name}/device/{test}' + fw_dir = f'cmake-build/cmake-build-{name}/{test}' if not os.path.exists(fw_dir): - fw_dir = f'examples/cmake-build-{name}/device/{test}' - fw_name = f'{fw_dir}/{test}' + fw_dir = f'examples/cmake-build-{name}/{test}' + fw_name = f'{fw_dir}/{os.path.basename(test)}' print(f'{name:30} {test:20} ... ', end='') if not os.path.exists(fw_dir): @@ -400,7 +428,7 @@ def test_board(board): if ret.returncode == 0: try: - ret = globals()[f'test_{test}'](board) + ret = globals()[f'test_{test.replace("/", "_")}'](board) print('OK') except Exception as e: err_count += 1 @@ -409,7 +437,6 @@ def test_board(board): else: err_count += 1 print('Flash failed') - return err_count diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 8eaca2621..3f07a8f42 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -8,11 +8,18 @@ "flasher_args": "-device nrf52840_xxaa" }, { - "name": "itsybitsy_m4", - "uid": "D784B28C5338533335202020FF044726", + "name": "metro_m4_express", + "uid": "9995AD485337433231202020FF100A34", "flasher": "openocd", - "flasher_sn": "E6614C311B597D32", - "flasher_args": "-f interface/cmsis-dap.cfg -f target/atsame5x.cfg -c \"adapter speed 5000\"" + "flasher_sn": "E6633861A3978538", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/atsame5x.cfg", + "tests": { + "dual_attached": [ + { + "vid_pid": "1a86_55d4", "serial": "52D2002130" + } + ] + } }, { "name": "max32666fthr", @@ -31,7 +38,9 @@ { "name": "ra4m1_ek", "uid": "152E163038303131393346E46F26574B", - "tests_skip": ["cdc_msc", "cdc_msc_freertos"], + "tests": { + "skip": ["device/cdc_msc", "device/cdc_msc_freertos"] + }, "comment": "MSC is slow to enumerated #2602", "flasher": "jlink", "flasher_sn": "000831174392", @@ -77,9 +86,9 @@ { "name": "espressif_s3_devkitm", "uid": "84F703C084E4", - "tests": [ - "cdc_msc_freertos", "hid_composite_freertos" - ], + "tests": { + "only": ["device/cdc_msc_freertos", "device/hid_composite_freertos"] + }, "flasher": "esptool", "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", "flasher_args": "-b 921600" -- cgit v1.3.1 From ccf886ca80ed74d985483fdb90e67703ebeb7dad Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Aug 2024 18:51:32 +0700 Subject: add pio-usb host test to hil. fix build as well --- hw/bsp/rp2040/family.c | 4 ++-- test/hil/rpi.json | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index 250989ce9..64a3a0af6 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -42,7 +42,7 @@ static uart_inst_t *uart_inst; #endif -#if CFG_TUH_RPI_PIO_USB || CFG_TUD_RPI_PIO_USB +#if (CFG_TUH_ENABLED && CFG_TUH_RPI_PIO_USB) || (CFG_TUD_ENABLED && CFG_TUD_RPI_PIO_USB) #include "pio_usb.h" #endif @@ -126,7 +126,7 @@ void stdio_rtt_init(void) { void board_init(void) { -#if CFG_TUH_RPI_PIO_USB || CFG_TUD_RPI_PIO_USB +#if (CFG_TUH_ENABLED && CFG_TUH_RPI_PIO_USB) || (CFG_TUD_ENABLED && CFG_TUD_RPI_PIO_USB) // Set the system clock to a multiple of 120mhz for bitbanging USB with pico-usb set_sys_clock_khz(120000, true); diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 3f07a8f42..b75c1339b 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -14,11 +14,7 @@ "flasher_sn": "E6633861A3978538", "flasher_args": "-f interface/cmsis-dap.cfg -f target/atsame5x.cfg", "tests": { - "dual_attached": [ - { - "vid_pid": "1a86_55d4", "serial": "52D2002130" - } - ] + "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002130"}] } }, { @@ -51,7 +47,10 @@ "uid": "E6614C311B764A37", "flasher": "openocd", "flasher_sn": "E6614103E72C1D2F", - "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"" + "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"", + "tests": { + "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002470"}] + } }, { "name": "stm32f072disco", -- cgit v1.3.1 From 45d06cd4ab2adea07513243447b6ec729d7d8c2c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Aug 2024 22:25:14 +0700 Subject: skip dual/host_info_to_device_cdc for pico due to a bug in pio-usb --- hw/bsp/family_support.cmake | 2 +- hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake | 2 +- test/hil/rpi.json | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 1df8a6f53..b457fcfac 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -463,7 +463,7 @@ function(family_flash_openocd TARGET) # note skip verify since it has issue with rp2040 add_custom_target(${TARGET}-openocd DEPENDS ${TARGET} - COMMAND ${OPENOCD} ${OPTION_LIST} -c init -c halt -c "program $ reset" ${OPTION_LIST2} -c exit + COMMAND ${OPENOCD} -c "tcl_port disabled" -c "gdb_port disabled" ${OPTION_LIST} -c init -c halt -c "program $" -c reset ${OPTION_LIST2} -c exit VERBATIM ) endfunction() diff --git a/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake b/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake index 6ff1a7b59..a0282aa23 100644 --- a/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake +++ b/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake @@ -2,7 +2,7 @@ set(MCU_VARIANT nrf52840) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) # enable max3421 host driver for this board -set(MAX3421_HOST 1) +# set(MAX3421_HOST 1) function(update_board TARGET) endfunction() diff --git a/test/hil/rpi.json b/test/hil/rpi.json index b75c1339b..7821f1660 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -49,6 +49,7 @@ "flasher_sn": "E6614103E72C1D2F", "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"", "tests": { + "skip": ["dual/host_info_to_device_cdc"], "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002470"}] } }, -- cgit v1.3.1 From 5bb2e66ce774fe174742f0893d82cb7895285983 Mon Sep 17 00:00:00 2001 From: Cumhur Onat Date: Sun, 21 Jul 2024 21:22:19 -0400 Subject: fix for out retry attempts with nak response --- src/portable/analog/max3421/hcd_max3421.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index d9b8e1fc3..342edef89 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -203,12 +203,13 @@ typedef struct { uint16_t packet_size : 11; }; + bool received_nak; uint16_t total_len; uint16_t xferred_len; uint8_t* buf; } max3421_ep_t; -TU_VERIFY_STATIC(sizeof(max3421_ep_t) == 12, "size is not correct"); +TU_VERIFY_STATIC(sizeof(max3421_ep_t) == 16, "size is not correct"); typedef struct { volatile uint16_t frame_count; @@ -625,12 +626,17 @@ static void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_i reg_write(rhport, HCTL_ADDR, hctl, in_isr); } - uint8_t const xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size); - TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,); - if (xact_len) { - fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr); + if (!ep->received_nak){ + // do not write to fifo or sdnbc register again if previous attempt got NAK + uint8_t const xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size); + TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,); + if (xact_len) { + fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr); + } + + sndbc_write(rhport, xact_len, in_isr); } - sndbc_write(rhport, xact_len, in_isr); + hxfr_write(rhport, ep->hxfr, in_isr); } @@ -844,6 +850,7 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { return; } else if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) { ep->state++; + ep->received_nak = true; } } @@ -867,6 +874,7 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { case HRSL_SUCCESS: xfer_result = XFER_RESULT_SUCCESS; + ep->received_nak = false; break; case HRSL_STALL: -- cgit v1.3.1 From c7851e8dcbdac8f895cfe81f2479bc6fcfcc524a Mon Sep 17 00:00:00 2001 From: Cumhur Onat Date: Sun, 21 Jul 2024 23:32:48 -0400 Subject: only check SNDBAV IRQ if there is data to send --- src/portable/analog/max3421/hcd_max3421.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 342edef89..3d054b66e 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -629,8 +629,9 @@ static void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_i if (!ep->received_nak){ // do not write to fifo or sdnbc register again if previous attempt got NAK uint8_t const xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size); - TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,); if (xact_len) { + // only check SNDBAV IRQ if there is data to send + TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,); fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr); } -- cgit v1.3.1 From 27ddf19631d135df15f3388686f59e379e146dbb Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 26 Aug 2024 12:24:29 +0700 Subject: add sndfifo owner info to skip rewriting data for retrying NAKed --- README.rst | 2 +- hw/bsp/family_support.cmake | 6 + src/host/usbh.h | 2 +- src/portable/analog/max3421/hcd_max3421.c | 191 +++++++++++++++++++----------- 4 files changed, 127 insertions(+), 74 deletions(-) diff --git a/README.rst b/README.rst index 6dd0e2714..2ffe3823a 100644 --- a/README.rst +++ b/README.rst @@ -197,7 +197,7 @@ Docs - `Structure`_ - `Porting`_ -.. |Build Status| image:: https://github.com/hathach/tinyusb/actions/workflows/cmake_arm.yml/badge.svg +.. |Build Status| image:: https://github.com/hathach/tinyusb/actions/workflows/build.yml/badge.svg :target: https://github.com/hathach/tinyusb/actions .. |CircleCI Status| image:: https://dl.circleci.com/status-badge/img/circleci/4AYHvUhFxdnY4rA7LEsdqW/QmrpoL2AjGqetvFQNqtWyq/tree/master.svg?style=svg :target: https://dl.circleci.com/status-badge/redirect/circleci/4AYHvUhFxdnY4rA7LEsdqW/QmrpoL2AjGqetvFQNqtWyq/tree/master diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index b457fcfac..aa5e037d1 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -418,6 +418,12 @@ exit" COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} ${OPTION_LIST} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile $/${TARGET}.jlink VERBATIM ) + + # optional flash post build +# add_custom_command(TARGET ${TARGET} POST_BUILD +# COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} ${OPTION_LIST} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile $/${TARGET}.jlink +# VERBATIM +# ) endfunction() diff --git a/src/host/usbh.h b/src/host/usbh.h index 359684169..d0a5732e5 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -81,7 +81,7 @@ enum { }; typedef struct { - uint8_t max_nak; // max NAK per endpoint per frame + uint8_t max_nak; // max NAK per endpoint per frame to save CPU/SPI bus usage uint8_t cpuctl; // R16: CPU Control Register uint8_t pinctl; // R17: Pin Control Register. FDUPSPI bit is ignored } tuh_configure_max3421_t; diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 3d054b66e..215feb481 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -168,14 +168,14 @@ enum { }; enum { - MAX_NAK_DEFAULT = 1 // Number of NAK per endpoint per usb frame + MAX_NAK_DEFAULT = 1 // Number of NAK per endpoint per usb frame to save CPU/SPI bus usage }; enum { EP_STATE_IDLE = 0, EP_STATE_COMPLETE = 1, EP_STATE_ABORTING = 2, - EP_STATE_ATTEMPT_1 = 3, // pending 1st attempt + EP_STATE_ATTEMPT_1 = 3, // Number of attempts to transfer in a frame. Incremented after each NAK EP_STATE_ATTEMPT_MAX = 15 }; @@ -183,17 +183,20 @@ enum { // //--------------------------------------------------------------------+ +typedef struct TU_ATTR_PACKED { + uint8_t ep_num : 4; + uint8_t is_setup : 1; + uint8_t is_out : 1; + uint8_t is_iso : 1; +} hxfr_bm_t; + +TU_VERIFY_STATIC(sizeof(hxfr_bm_t) == 1, "size is not correct"); + typedef struct { uint8_t daddr; - union { ; - struct TU_ATTR_PACKED { - uint8_t ep_num : 4; - uint8_t is_setup : 1; - uint8_t is_out : 1; - uint8_t is_iso : 1; - }hxfr_bm; - + union { + hxfr_bm_t hxfr_bm; uint8_t hxfr; }; @@ -203,13 +206,12 @@ typedef struct { uint16_t packet_size : 11; }; - bool received_nak; uint16_t total_len; uint16_t xferred_len; uint8_t* buf; } max3421_ep_t; -TU_VERIFY_STATIC(sizeof(max3421_ep_t) == 16, "size is not correct"); +TU_VERIFY_STATIC(sizeof(max3421_ep_t) == 12, "size is not correct"); typedef struct { volatile uint16_t frame_count; @@ -220,7 +222,16 @@ typedef struct { uint8_t hien; uint8_t mode; uint8_t peraddr; - uint8_t hxfr; + union { + hxfr_bm_t hxfr_bm; + uint8_t hxfr; + }; + + // owner of data in SNDFIFO, for retrying NAKed without re-writing to FIFO + struct { + uint8_t daddr; + uint8_t hxfr; + }sndfifo_owner; atomic_flag busy; // busy transferring @@ -318,33 +329,9 @@ bool tuh_max3421_reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_is return ret; } -static void fifo_write(uint8_t rhport, uint8_t reg, uint8_t const * buffer, uint16_t len, bool in_isr) { - uint8_t hirq; - reg |= CMDBYTE_WRITE; - - max3421_spi_lock(rhport, in_isr); - - tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1); - _hcd_data.hirq = hirq; - tuh_max3421_spi_xfer_api(rhport, buffer, NULL, len); - - max3421_spi_unlock(rhport, in_isr); -} - -static void fifo_read(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_isr) { - uint8_t hirq; - uint8_t const reg = RCVVFIFO_ADDR; - - max3421_spi_lock(rhport, in_isr); - - tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1); - _hcd_data.hirq = hirq; - tuh_max3421_spi_xfer_api(rhport, NULL, buffer, len); - - max3421_spi_unlock(rhport, in_isr); -} - -//------------- register write helper -------------// +//-------------------------------------------------------------------- +// Register helper +//-------------------------------------------------------------------- TU_ATTR_ALWAYS_INLINE static inline void hirq_write(uint8_t rhport, uint8_t data, bool in_isr) { reg_write(rhport, HIRQ_ADDR, data, in_isr); // HIRQ write 1 is clear @@ -378,6 +365,47 @@ TU_ATTR_ALWAYS_INLINE static inline void sndbc_write(uint8_t rhport, uint8_t dat reg_write(rhport, SNDBC_ADDR, data, in_isr); } +//-------------------------------------------------------------------- +// FIFO access (receive, send, setup) +//-------------------------------------------------------------------- +static void hwfifo_write(uint8_t rhport, uint8_t reg, const uint8_t* buffer, uint8_t len, bool in_isr) { + uint8_t hirq; + reg |= CMDBYTE_WRITE; + + max3421_spi_lock(rhport, in_isr); + + tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1); + _hcd_data.hirq = hirq; + tuh_max3421_spi_xfer_api(rhport, buffer, NULL, len); + + max3421_spi_unlock(rhport, in_isr); +} + +// Write to SNDFIFO if len > 0 and update SNDBC +TU_ATTR_ALWAYS_INLINE static inline void hwfifo_send(uint8_t rhport, const uint8_t* buffer, uint8_t len, bool in_isr) { + if (len) { + hwfifo_write(rhport, SNDFIFO_ADDR, buffer, len, in_isr); + } + sndbc_write(rhport, len, in_isr); +} + +TU_ATTR_ALWAYS_INLINE static inline void hwfifo_setup(uint8_t rhport, const uint8_t* buffer, bool in_isr) { + hwfifo_write(rhport, SUDFIFO_ADDR, buffer, 8, in_isr); +} + +static void hwfifo_receive(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_isr) { + uint8_t hirq; + uint8_t const reg = RCVVFIFO_ADDR; + + max3421_spi_lock(rhport, in_isr); + + tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1); + _hcd_data.hirq = hirq; + tuh_max3421_spi_xfer_api(rhport, NULL, buffer, len); + + max3421_spi_unlock(rhport, in_isr); +} + //--------------------------------------------------------------------+ // Endpoint helper //--------------------------------------------------------------------+ @@ -418,7 +446,7 @@ static void free_ep(uint8_t daddr) { } } -// Check if endpoint has an queued transfer and not reach max NAK +// Check if endpoint has a queued transfer and not reach max NAK in this frame TU_ATTR_ALWAYS_INLINE static inline bool is_ep_pending(max3421_ep_t const * ep) { uint8_t const state = ep->state; return ep->packet_size && (state >= EP_STATE_ATTEMPT_1) && @@ -488,6 +516,7 @@ bool hcd_init(uint8_t rhport) { reg_write(rhport, PINCTL_ADDR, _tuh_cfg.pinctl | PINCTL_FDUPSPI, false); // v1 is 0x01, v2 is 0x12, v3 is 0x13 + // Note: v1 and v2 has host OUT errata whose workaround is not implemented in this driver uint8_t const revision = reg_read(rhport, REVISION_ADDR, false); TU_LOG2_HEX(revision); TU_ASSERT(revision == 0x01 || revision == 0x12 || revision == 0x13, false); @@ -616,27 +645,44 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t daddr, tusb_desc_endpoint_t const * e return true; } +/* The microcontroller repeatedly writes the SNDFIFO register R2 to load the FIFO with up to 64 data bytes. + * Then the microcontroller writes the SNDBC register, which this does three things: + * 1. Tells the MAX3421E SIE (Serial Interface Engine) how many bytes in the FIFO to send. + * 2. Connects the SNDFIFO and SNDBC register to the USB logic for USB transmission. + * 3. Clears the SNDBAVIRQ interrupt flag. If the second FIFO is available for µC loading, the SNDBAVIRQ immediately re-asserts. + + +-----------+ + --->| SNDBC-A | + / | SNDFIFO-A | + / +-----------+ + +------+ +-------------+ / +----------+ + | MCU |------>| R2: SNDFIFO |---- << Write R7 Flip >> ---| MAX3241E | + |(hcd) | | R7: SNDBC | / | SIE | + +------+ +-------------+ / +----------+ + +-----------+ / + | SNDBC-B | / + | SNDFIFO-B |<--- + +-----------+ + Note: xact_out() is called when starting a new transfer, continue a transfer (isr) or retry a transfer (NAK) + For NAK retry, we do not need to write to FIFO or SNDBC register again. +*/ static void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { // Page 12: Programming BULK-OUT Transfers - // TODO double buffered + // TODO: double buffering for ISO transfer if (switch_ep) { peraddr_write(rhport, ep->daddr, in_isr); - - uint8_t const hctl = (ep->data_toggle ? HCTL_SNDTOG1 : HCTL_SNDTOG0); + const uint8_t hctl = (ep->data_toggle ? HCTL_SNDTOG1 : HCTL_SNDTOG0); reg_write(rhport, HCTL_ADDR, hctl, in_isr); } - if (!ep->received_nak){ - // do not write to fifo or sdnbc register again if previous attempt got NAK - uint8_t const xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size); - if (xact_len) { - // only check SNDBAV IRQ if there is data to send - TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,); - fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr); - } - - sndbc_write(rhport, xact_len, in_isr); + // Only write to sndfifo and sdnbc register if it is not a NAKed retry + if (!(ep->daddr == _hcd_data.sndfifo_owner.daddr && ep->hxfr == _hcd_data.sndfifo_owner.hxfr)) { + // skip SNDBAV IRQ check, overwrite sndfifo if needed + const uint8_t xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size); + hwfifo_send(rhport, ep->buf, xact_len, in_isr); } + _hcd_data.sndfifo_owner.daddr = ep->daddr; + _hcd_data.sndfifo_owner.hxfr = ep->hxfr; hxfr_write(rhport, ep->hxfr, in_isr); } @@ -655,7 +701,7 @@ static void xact_in(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_is static void xact_setup(uint8_t rhport, max3421_ep_t *ep, bool in_isr) { peraddr_write(rhport, ep->daddr, in_isr); - fifo_write(rhport, SUDFIFO_ADDR, ep->buf, 8, in_isr); + hwfifo_setup(rhport, ep->buf, in_isr); hxfr_write(rhport, HXFR_SETUP, in_isr); } @@ -669,7 +715,7 @@ static void xact_generic(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool // status if (ep->buf == NULL || ep->total_len == 0) { - uint8_t const hxfr = (uint8_t) (HXFR_HS | (ep->hxfr & HXFR_OUT_NIN)); + const uint8_t hxfr = (uint8_t) (HXFR_HS | (ep->hxfr & HXFR_OUT_NIN)); peraddr_write(rhport, ep->daddr, in_isr); hxfr_write(rhport, hxfr, in_isr); return; @@ -830,11 +876,11 @@ static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t re } static void handle_xfer_done(uint8_t rhport, bool in_isr) { - uint8_t const hrsl = reg_read(rhport, HRSL_ADDR, in_isr); - uint8_t const hresult = hrsl & HRSL_RESULT_MASK; - uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK; - uint8_t const hxfr_type = _hcd_data.hxfr & 0xf0; - uint8_t const ep_dir = ((hxfr_type & HXFR_SETUP) || (hxfr_type & HXFR_OUT_NIN)) ? 0 : 1; + const uint8_t hrsl = reg_read(rhport, HRSL_ADDR, in_isr); + const uint8_t hresult = hrsl & HRSL_RESULT_MASK; + const uint8_t ep_num = _hcd_data.hxfr_bm.ep_num; + const uint8_t hxfr_type = _hcd_data.hxfr & 0xf0; + const uint8_t ep_dir = ((hxfr_type & HXFR_SETUP) || (hxfr_type & HXFR_OUT_NIN)) ? 0 : 1; max3421_ep_t *ep = find_opened_ep(_hcd_data.peraddr, ep_num, ep_dir); TU_VERIFY(ep, ); @@ -849,9 +895,9 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { // control endpoint -> retry immediately and return hxfr_write(rhport, _hcd_data.hxfr, in_isr); return; - } else if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) { + } + if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) { ep->state++; - ep->received_nak = true; } } @@ -861,7 +907,6 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { hxfr_write(rhport, _hcd_data.hxfr, in_isr); } else if (next_ep) { // switch to next pending endpoint - // TODO could have issue with double buffered if not clear previously out data xact_generic(rhport, next_ep, true, in_isr); } else { // no more pending in this frame -> clear busy @@ -875,7 +920,6 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { case HRSL_SUCCESS: xfer_result = XFER_RESULT_SUCCESS; - ep->received_nak = false; break; case HRSL_STALL: @@ -905,11 +949,15 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { if (ep->state == EP_STATE_COMPLETE) { xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); }else { - // more to transfer - hxfr_write(rhport, _hcd_data.hxfr, in_isr); + hxfr_write(rhport, _hcd_data.hxfr, in_isr); // more to transfer } } else { // SETUP or OUT transfer + + // clear sndfifo owner since data is sent + _hcd_data.sndfifo_owner.daddr = 0xff; + _hcd_data.sndfifo_owner.hxfr = 0xff; + uint8_t xact_len; if (hxfr_type & HXFR_SETUP) { @@ -926,8 +974,7 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { if (xact_len < ep->packet_size || ep->xferred_len >= ep->total_len) { xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); } else { - // more to transfer - xact_out(rhport, ep, false, in_isr); + xact_out(rhport, ep, false, in_isr); // more to transfer } } } @@ -987,16 +1034,16 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { // not call this handler again. So we need to loop until all IRQ are cleared while (hirq & (HIRQ_RCVDAV_IRQ | HIRQ_HXFRDN_IRQ)) { if (hirq & HIRQ_RCVDAV_IRQ) { - uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK; + const uint8_t ep_num = _hcd_data.hxfr_bm.ep_num; max3421_ep_t* ep = find_opened_ep(_hcd_data.peraddr, ep_num, 1); uint8_t xact_len = 0; // RCVDAV_IRQ can trigger 2 times (dual buffered) while (hirq & HIRQ_RCVDAV_IRQ) { - uint8_t rcvbc = reg_read(rhport, RCVBC_ADDR, in_isr); + const uint8_t rcvbc = reg_read(rhport, RCVBC_ADDR, in_isr); xact_len = (uint8_t) tu_min16(rcvbc, ep->total_len - ep->xferred_len); if (xact_len) { - fifo_read(rhport, ep->buf, xact_len, in_isr); + hwfifo_receive(rhport, ep->buf, xact_len, in_isr); ep->buf += xact_len; ep->xferred_len += xact_len; } -- cgit v1.3.1 From 29d4c82efb9654aa8739cd806a9e81d37830e23e Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 27 Aug 2024 16:38:26 +0700 Subject: reset usb when init for max32650/66. change hil max32 to use pico (cmsis dap2), change metro m4 flasher --- hw/bsp/max32650/family.c | 1 + hw/bsp/max32650/family.cmake | 2 +- hw/bsp/max32666/family.c | 1 + test/hil/rpi.json | 19 ++++++------------- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/hw/bsp/max32650/family.c b/hw/bsp/max32650/family.c index 89a5db160..bb382cdd4 100644 --- a/hw/bsp/max32650/family.c +++ b/hw/bsp/max32650/family.c @@ -94,6 +94,7 @@ void board_init(void) { } MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB); + MXC_SYS_Reset_Periph(MXC_SYS_RESET_USB); } //--------------------------------------------------------------------+ diff --git a/hw/bsp/max32650/family.cmake b/hw/bsp/max32650/family.cmake index e05bd7652..48853b92c 100644 --- a/hw/bsp/max32650/family.cmake +++ b/hw/bsp/max32650/family.cmake @@ -148,10 +148,10 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_jlink(${TARGET}) + family_flash_openocd_adi(${TARGET}) # Add the optional MSDK OpenOCD flashing family_flash_msdk(${TARGET}) - family_flash_openocd_adi(${TARGET}) endfunction() function(family_flash_msdk TARGET) diff --git a/hw/bsp/max32666/family.c b/hw/bsp/max32666/family.c index 8ee4b6762..f96393fe1 100644 --- a/hw/bsp/max32666/family.c +++ b/hw/bsp/max32666/family.c @@ -93,6 +93,7 @@ void board_init(void) { } MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB); + MXC_SYS_Reset_Periph(MXC_SYS_RESET_USB); } //--------------------------------------------------------------------+ diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 7821f1660..259f8ca83 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -10,9 +10,9 @@ { "name": "metro_m4_express", "uid": "9995AD485337433231202020FF100A34", - "flasher": "openocd", - "flasher_sn": "E6633861A3978538", - "flasher_args": "-f interface/cmsis-dap.cfg -f target/atsame5x.cfg", + "flasher": "jlink", + "flasher_sn": "123456", + "flasher_args": "-device ATSAMD51J19", "tests": { "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002130"}] } @@ -20,9 +20,9 @@ { "name": "max32666fthr", "uid": "0C81464124010B20FF0A08CC2C", - "flasher": "jlink", - "flasher_sn": "000801011822", - "flasher_args": "-device max32666" + "flasher": "openocd_adi", + "flasher_sn": "E6614C311B597D32", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/max32665.cfg" }, { "name": "lpcxpresso11u37", @@ -92,13 +92,6 @@ "flasher": "esptool", "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", "flasher_args": "-b 921600" - }, - { - "name": "max32666fthr", - "uid": "0C81464124010B20FF0A08CC2C", - "flasher": "openocd_adi", - "flasher_sn": "042217023bffc88100000000000000000000000097969906", - "flasher_args": "-f interface/cmsis-dap.cfg -f target/max32665.cfg" } ] } -- cgit v1.3.1 From 6fdf206f11f3c540b1930693826a469f3ffcc240 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 28 Aug 2024 11:43:14 +0700 Subject: bump up pio-usb to 0.6.1, enable dual hil test for pico --- test/hil/hil_test.py | 18 ++++++++++++------ test/hil/rpi.json | 1 - tools/get_deps.py | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 5a4799cfb..52ec5ae1d 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -39,6 +39,9 @@ import fs ENUM_TIMEOUT = 30 +STATUS_OK = "\033[32mOK\033[0m" +STATUS_FAILED = "\033[31mFailed\033[0m" +STATUS_SKIPPED = "\033[33mSkipped\033[0m" # get usb serial by id def get_serial_dev(id, vendor_str, product_str, ifnum): @@ -411,7 +414,7 @@ def test_board(board): if not os.path.exists(fw_dir): fw_dir = f'examples/cmake-build-{name}/{test}' fw_name = f'{fw_dir}/{os.path.basename(test)}' - print(f'{name:30} {test:20} ... ', end='') + print(f'{name:25} {test:30} ... ', end='') if not os.path.exists(fw_dir): print('Skip') @@ -432,11 +435,11 @@ def test_board(board): print('OK') except Exception as e: err_count += 1 - print('Failed') + print(STATUS_FAILED) print(f' {e}') else: err_count += 1 - print('Flash failed') + print(f'Flash {STATUS_FAILED}') return err_count @@ -463,10 +466,13 @@ def main(): else: config_boards = [e for e in config['boards'] if e['name'] in boards] - err_count_list = [] with Pool(processes=os.cpu_count()) as pool: - err_count_list = pool.map(test_board, config_boards) - err_count = sum(err_count_list) + err_count = sum(pool.map(test_board, config_boards)) + + print() + print("-" * 30) + print(f'Total failed: {err_count}') + print("-" * 30) sys.exit(err_count) diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 259f8ca83..36376a873 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -49,7 +49,6 @@ "flasher_sn": "E6614103E72C1D2F", "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"", "tests": { - "skip": ["dual/host_info_to_device_cdc"], "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002470"}] } }, diff --git a/tools/get_deps.py b/tools/get_deps.py index f141d3d41..06da54b41 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -58,7 +58,7 @@ deps_optional = { '144f1eb7ea8c06512e12f12b27383601c0272410', 'kinetis_k kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx imxrt'], 'hw/mcu/raspberry_pi/Pico-PIO-USB': ['https://github.com/sekigon-gonnoc/Pico-PIO-USB.git', - '7902e9fa8ed4a271d8d1d5e7e50516c2292b7bc2', + 'fe9133fc513b82cc3dc62c67cb51f2339cf29ef7', 'rp2040'], 'hw/mcu/renesas/fsp': ['https://github.com/renesas/fsp.git', 'd52e5a6a59b7c638da860c2bb309b6e78e752ff8', -- cgit v1.3.1 From 9985b9faf41c2376c9b14a8f60cc1893c8bb4ac6 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 28 Aug 2024 12:20:44 +0700 Subject: try to build hil in parallel --- .github/workflows/hil_test.yml | 58 +++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index d02f13e05..087374be2 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -21,51 +21,53 @@ env: HIL_JSON: test/hil/rpi.json jobs: - # --------------------------------------- - # Build Non Espressif - # --------------------------------------- - build: - if: github.repository_owner == 'hathach' + set-matrix: runs-on: ubuntu-latest outputs: - BOARDS_LIST: ${{ steps.parse_hil_json.outputs.BOARDS_LIST }} + json: ${{ steps.set-matrix-json.outputs.matrix }} steps: - name: Checkout TinyUSB uses: actions/checkout@v4 - - name: Parse HIL json - id: parse_hil_json + - name: Generate matrix json + id: set-matrix-json run: | - sudo apt install -y jq + MATRIX_JSON=$(jq -c '{ "arm-gcc": [.boards[] | select(.flasher != "esptool" and .flasher != "openocd_wch") | .name] }' ${{ env.HIL_JSON }}) + echo "matrix=$MATRIX_JSON" + echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT - # Non-Espresif boards - BOARDS_LIST=$(jq -r '.boards[] | select(.flasher != "esptool") | "-b " + .name' ${{ env.HIL_JSON }} | tr '\n' ' ') - echo "BOARDS_LIST=$BOARDS_LIST" - echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV - echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT + # --------------------------------------- + # Build arm-gcc + # --------------------------------------- + build: + if: github.repository_owner == 'hathach' + needs: set-matrix + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + board: ${{ fromJSON(needs.set-matrix.outputs.json)['arm-gcc'] }} + steps: + - name: Checkout TinyUSB + uses: actions/checkout@v4 - name: Setup arm-gcc toolchain uses: ./.github/actions/setup_toolchain with: toolchain: 'arm-gcc' - - name: Setup risv-gcc toolchain - uses: ./.github/actions/setup_toolchain - with: - toolchain: 'riscv-gcc' - - name: Get Dependencies uses: ./.github/actions/get_deps with: - arg: ${{ env.BOARDS_LIST }} + arg: -b${{ matrix.board }} - name: Build - run: python tools/build.py $BOARDS_LIST + run: python tools/build.py -b${{ matrix.board }} - name: Upload Artifacts for Hardware Testing uses: actions/upload-artifact@v4 with: - name: hil_rpi + name: ${{ matrix.board }} path: | cmake-build/cmake-build-*/*/*/*.elf cmake-build/cmake-build-*/*/*/*.bin @@ -76,11 +78,8 @@ jobs: # --------------------------------------- hil-rpi: if: github.repository_owner == 'hathach' - needs: - - build + needs: build runs-on: [self-hosted, ARM64, rpi, hardware-in-the-loop] - env: - BOARDS_LIST: "${{ needs.build-esp.outputs.BOARDS_LIST }} ${{ needs.build.outputs.BOARDS_LIST }}" steps: - name: Clean workspace run: | @@ -107,9 +106,4 @@ jobs: merge-multiple: true - name: Test on actual hardware - run: | - echo "BOARDS_LIST=$BOARDS_LIST" - echo "::group::{cmake-build contents}" - tree cmake-build - echo "::endgroup::" - python3 test/hil/hil_test.py $BOARDS_LIST ${{ env.HIL_JSON }} + run: python3 test/hil/hil_test.py ${{ env.HIL_JSON }} -- cgit v1.3.1 From 59883237f71743d2e6664d1e244394c5757856d6 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 28 Aug 2024 13:07:52 +0700 Subject: enable rx-gcc for circleci --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5136d6331..83f554916 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -24,7 +24,7 @@ jobs: "make arm-gcc" "make msp430-gcc" "make riscv-gcc" - # "make rx-gcc" llvm-gcc-renesas.com seems to be down + "make rx-gcc" "cmake esp-idf" ) -- cgit v1.3.1 From 973cbd33388a5505a60ea1b70bbfd8b5c74c9c1e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 28 Aug 2024 14:24:50 +0700 Subject: enable i386 arch for running rx-gcc --- .circleci/config2.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.circleci/config2.yml b/.circleci/config2.yml index 70b5c60ac..e076baeb7 100644 --- a/.circleci/config2.yml +++ b/.circleci/config2.yml @@ -42,6 +42,10 @@ commands: if [[ << parameters.toolchain >> == rx-gcc ]]; then mv toolchain.tar.gz toolchain.run chmod +x toolchain.run + # rx-gcc is i386 binary + sudo dpkg --add-architecture i386 + sudo apt update + sudo apt install libc6:i386 libncurses5:i386 libstdc++6:i386 ./toolchain.run -p ~/cache/<< parameters.toolchain >>/gnurx -y else tar -C ~/cache/<< parameters.toolchain >> -xaf toolchain.tar.gz -- cgit v1.3.1 From 0d542a0bdc3931aa82469db5d2b8c329ea5aa2e9 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 28 Aug 2024 14:44:32 +0700 Subject: enable i386 arch for running rx-gcc --- .circleci/config2.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.circleci/config2.yml b/.circleci/config2.yml index e076baeb7..542c3d0d0 100644 --- a/.circleci/config2.yml +++ b/.circleci/config2.yml @@ -42,10 +42,6 @@ commands: if [[ << parameters.toolchain >> == rx-gcc ]]; then mv toolchain.tar.gz toolchain.run chmod +x toolchain.run - # rx-gcc is i386 binary - sudo dpkg --add-architecture i386 - sudo apt update - sudo apt install libc6:i386 libncurses5:i386 libstdc++6:i386 ./toolchain.run -p ~/cache/<< parameters.toolchain >>/gnurx -y else tar -C ~/cache/<< parameters.toolchain >> -xaf toolchain.tar.gz @@ -92,6 +88,13 @@ commands: unzip ninja-linux.zip -d ~/bin fi + # rx-gcc is 32-bit binary + if [[ << parameters.toolchain >> == rx-gcc ]]; then + sudo dpkg --add-architecture i386 + sudo apt update + sudo apt install libc6:i386 libstdc++6:i386 zlib1g:i386 + fi + # Install Pico SDK if [ << parameters.family >> == "rp2040" ]; then git clone --depth 1 https://github.com/raspberrypi/pico-sdk.git ~/pico-sdk -- cgit v1.3.1 From f73964e3e59645757a7311f2b4fe7c1c9d868e12 Mon Sep 17 00:00:00 2001 From: Andrew Scheller Date: Wed, 28 Aug 2024 13:30:48 +0100 Subject: Fix compiler warning in hid_boot_interface example --- examples/device/hid_boot_interface/src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/device/hid_boot_interface/src/main.c b/examples/device/hid_boot_interface/src/main.c index 7ad5c53c2..c2aef502d 100644 --- a/examples/device/hid_boot_interface/src/main.c +++ b/examples/device/hid_boot_interface/src/main.c @@ -161,8 +161,8 @@ void hid_task(void) { uint8_t const report_id = 0; uint8_t const button_mask = 0; - uint8_t const vertical = 0; - uint8_t const horizontal = 0; + int8_t const vertical = 0; + int8_t const horizontal = 0; int8_t const delta = 5; tud_hid_n_mouse_report(ITF_NUM_MOUSE, report_id, button_mask, delta, delta, vertical, horizontal); -- cgit v1.3.1 From 1d2c9f929dd3bfaf82741da30e8dbf97b0ff385c Mon Sep 17 00:00:00 2001 From: Reinhard Griech Date: Thu, 29 Aug 2024 15:31:29 +0200 Subject: change order, fixes #2778 --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 1cc5c1836..a63e442f3 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -441,11 +441,11 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE)); if (control_status) { - // Status Phase also requires EasyDMA has to be available as well !!!! - edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS); - // The nRF doesn't interrupt on status transmit so we queue up a success response. dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, is_in_isr()); + + // Status Phase also requires EasyDMA has to be available as well !!!! + edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS); } else if (dir == TUSB_DIR_OUT) { xfer->started = true; if (epnum == 0) { -- cgit v1.3.1 From 6890975f80bb541ba4f229cc1c3bc165745e21ac Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 29 Aug 2024 14:04:49 -0700 Subject: Fix ESP32-SX resume The interrupt handler pipes through the resume event but the interrupt wasn't enabled in the first place. --- src/portable/espressif/esp32sx/dcd_esp32sx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/portable/espressif/esp32sx/dcd_esp32sx.c b/src/portable/espressif/esp32sx/dcd_esp32sx.c index f912bef89..61911ab4c 100644 --- a/src/portable/espressif/esp32sx/dcd_esp32sx.c +++ b/src/portable/espressif/esp32sx/dcd_esp32sx.c @@ -207,6 +207,7 @@ void dcd_init(uint8_t rhport) USB_USBRSTMSK_M | USB_ENUMDONEMSK_M | USB_RESETDETMSK_M | + USB_WKUPINT_M | USB_DISCONNINTMSK_M; // host most only dcd_connect(rhport); -- cgit v1.3.1 From cef4c466b33609a26fe811d586f8644e9d421d2f Mon Sep 17 00:00:00 2001 From: Donatien Garnier Date: Thu, 29 Aug 2024 16:43:42 +0000 Subject: Bluetooth Device: Issue ZLP on ACL IN ep when transfer is multiple of endpoint max packet size --- src/class/bth/bth_device.c | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/class/bth/bth_device.c b/src/class/bth/bth_device.c index cbf6e1332..a79908627 100755 --- a/src/class/bth/bth_device.c +++ b/src/class/bth/bth_device.c @@ -42,10 +42,14 @@ typedef struct uint8_t itf_num; uint8_t ep_ev; uint8_t ep_acl_in; + uint16_t ep_acl_in_pkt_sz; uint8_t ep_acl_out; uint8_t ep_voice[2]; // Not used yet uint8_t ep_voice_size[2][CFG_TUD_BTH_ISO_ALT_COUNT]; + // Previous amount of bytes sent when issuing ZLP + uint32_t prev_xferred_bytes; + // Endpoint Transfer buffer CFG_TUSB_MEM_ALIGN bt_hci_cmd_t hci_cmd; CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_BTH_DATA_EPSIZE]; @@ -127,11 +131,25 @@ uint16_t btd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_ TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); _btd_itf.ep_ev = desc_ep->bEndpointAddress; + desc_ep = (tusb_desc_endpoint_t const *)tu_desc_next(desc_ep); + // Open endpoint pair - TU_ASSERT(usbd_open_edpt_pair(rhport, tu_desc_next(desc_ep), 2, TUSB_XFER_BULK, &_btd_itf.ep_acl_out, - &_btd_itf.ep_acl_in), 0); + TU_ASSERT(usbd_open_edpt_pair(rhport, (uint8_t const *)desc_ep, 2, + TUSB_XFER_BULK, &_btd_itf.ep_acl_out, + &_btd_itf.ep_acl_in), + 0); + + // Save acl in endpoint max packet size + tusb_desc_endpoint_t const *desc_ep_acl_in = desc_ep; + for (size_t p = 0; p < 2; p++) { + if (tu_edpt_dir(desc_ep_acl_in->bEndpointAddress) == TUSB_DIR_IN) { + _btd_itf.ep_acl_in_pkt_sz = tu_edpt_packet_size(desc_ep_acl_in); + break; + } + desc_ep_acl_in = (tusb_desc_endpoint_t const *)tu_desc_next(desc_ep_acl_in); + } - itf_desc = (tusb_desc_interface_t const *)tu_desc_next(tu_desc_next(tu_desc_next(desc_ep))); + itf_desc = (tusb_desc_interface_t const *)tu_desc_next(tu_desc_next(desc_ep)); // Prepare for incoming data from host TU_ASSERT(usbd_edpt_xfer(rhport, _btd_itf.ep_acl_out, _btd_itf.epout_buf, CFG_TUD_BTH_DATA_EPSIZE), 0); @@ -238,10 +256,8 @@ bool btd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t c return true; } -bool btd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ - (void)result; - +bool btd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, + uint32_t xferred_bytes) { // received new data from host if (ep_addr == _btd_itf.ep_acl_out) { @@ -256,7 +272,20 @@ bool btd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t } else if (ep_addr == _btd_itf.ep_acl_in) { - if (tud_bt_acl_data_sent_cb) tud_bt_acl_data_sent_cb((uint16_t)xferred_bytes); + if ((result == XFER_RESULT_SUCCESS) && (xferred_bytes > 0) && + ((xferred_bytes & (_btd_itf.ep_acl_in_pkt_sz - 1)) == 0)) { + // Save number of transferred bytes + _btd_itf.prev_xferred_bytes = xferred_bytes; + + // Send zero-length packet + tud_bt_acl_data_send(NULL, 0); + } else if (tud_bt_acl_data_sent_cb) { + if (xferred_bytes == 0) { + xferred_bytes = _btd_itf.prev_xferred_bytes; + _btd_itf.prev_xferred_bytes = 0; + } + tud_bt_acl_data_sent_cb((uint16_t)xferred_bytes); + } } return true; -- cgit v1.3.1 From 8ab1e4fbd01f9ec0f01cbfee26e72c73f8eeea44 Mon Sep 17 00:00:00 2001 From: dp111 <19616418+dp111@users.noreply.github.com> Date: Tue, 3 Sep 2024 19:38:34 +0100 Subject: make function prototypes match ( found by cppcheck) --- src/common/tusb_fifo.h | 8 ++++---- src/device/usbd_control.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 6c0efb509..879acda4f 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -154,14 +154,14 @@ void tu_fifo_config_mutex(tu_fifo_t *f, osal_mutex_t wr_mutex, osal_mutex_t rd_m #define tu_fifo_config_mutex(_f, _wr_mutex, _rd_mutex) #endif -bool tu_fifo_write (tu_fifo_t* f, void const * p_data); -uint16_t tu_fifo_write_n (tu_fifo_t* f, void const * p_data, uint16_t n); +bool tu_fifo_write (tu_fifo_t* f, void const * data); +uint16_t tu_fifo_write_n (tu_fifo_t* f, void const * data, uint16_t n); #ifdef TUP_MEM_CONST_ADDR uint16_t tu_fifo_write_n_const_addr_full_words (tu_fifo_t* f, const void * data, uint16_t n); #endif -bool tu_fifo_read (tu_fifo_t* f, void * p_buffer); -uint16_t tu_fifo_read_n (tu_fifo_t* f, void * p_buffer, uint16_t n); +bool tu_fifo_read (tu_fifo_t* f, void * buffer); +uint16_t tu_fifo_read_n (tu_fifo_t* f, void * buffer, uint16_t n); #ifdef TUP_MEM_CONST_ADDR uint16_t tu_fifo_read_n_const_addr_full_words (tu_fifo_t* f, void * buffer, uint16_t n); #endif diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 35cce1f7e..b1fd357aa 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -137,7 +137,7 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const* request, voi void usbd_control_reset(void); void usbd_control_set_request(tusb_control_request_t const* request); void usbd_control_set_complete_callback(usbd_control_xfer_cb_t fp); -bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); +bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); void usbd_control_reset(void) { tu_varclr(&_ctrl_xfer); -- cgit v1.3.1 From dde81f8f0347fe6cd73485aec717b96bf593eabc Mon Sep 17 00:00:00 2001 From: dp111 <19616418+dp111@users.noreply.github.com> Date: Tue, 3 Sep 2024 19:59:55 +0100 Subject: make function prototypes match definitions ( found with cppcheck) --- .../vendor/ceedling/vendor/unity/src/unity_internals.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/unit-test/vendor/ceedling/vendor/unity/src/unity_internals.h b/test/unit-test/vendor/ceedling/vendor/unity/src/unity_internals.h index 2c91b6db1..d66309f96 100644 --- a/test/unit-test/vendor/ceedling/vendor/unity/src/unity_internals.h +++ b/test/unit-test/vendor/ceedling/vendor/unity/src/unity_internals.h @@ -632,14 +632,14 @@ void UnityAssertNumbersArrayWithin(const UNITY_UINT delta, const UNITY_FLAGS_T flags); #ifndef UNITY_EXCLUDE_SETJMP_H -UNITY_NORETURN void UnityFail(const char* message, const UNITY_LINE_TYPE line); -UNITY_NORETURN void UnityIgnore(const char* message, const UNITY_LINE_TYPE line); +UNITY_NORETURN void UnityFail(const char* msg, const UNITY_LINE_TYPE line); +UNITY_NORETURN void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line); #else -void UnityFail(const char* message, const UNITY_LINE_TYPE line); -void UnityIgnore(const char* message, const UNITY_LINE_TYPE line); +void UnityFail(const char* msg, const UNITY_LINE_TYPE line); +void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line); #endif -void UnityMessage(const char* message, const UNITY_LINE_TYPE line); +void UnityMessage(const char* msg, const UNITY_LINE_TYPE line); #ifndef UNITY_EXCLUDE_FLOAT void UnityAssertFloatsWithin(const UNITY_FLOAT delta, -- cgit v1.3.1 From fc07df320bf20ed5b3d78ad181d8af1533e12c12 Mon Sep 17 00:00:00 2001 From: dp111 <19616418+dp111@users.noreply.github.com> Date: Tue, 3 Sep 2024 20:28:42 +0100 Subject: use fixed with in printf ( found by clang) NB %lu is a minimum of 32 bits where as the variable use is exactly 32 bits . This can affect porting to other systems. --- examples/typec/power_delivery/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/typec/power_delivery/src/main.c b/examples/typec/power_delivery/src/main.c index 489d01aa1..a8214f34e 100644 --- a/examples/typec/power_delivery/src/main.c +++ b/examples/typec/power_delivery/src/main.c @@ -98,7 +98,7 @@ bool tuc_pd_data_received_cb(uint8_t rhport, pd_header_t const* header, uint8_t pd_pdo_fixed_t const* fixed = (pd_pdo_fixed_t const*) &pdo; uint32_t const voltage_mv = fixed->voltage_50mv*50; uint32_t const current_ma = fixed->current_max_10ma*10; - printf("[Fixed] %lu mV %lu mA\r\n", voltage_mv, current_ma); + printf("[Fixed] %"PRIu32" mV %"PRIu32" mA\r\n", voltage_mv, current_ma); if (voltage_mv <= VOLTAGE_MAX_MV && current_ma >= CURRENT_MAX_MA) { // Found a suitable PDO -- cgit v1.3.1 From 6935c663094bbba58e03c7820f4c2893fbce61a1 Mon Sep 17 00:00:00 2001 From: dp111 <19616418+dp111@users.noreply.github.com> Date: Tue, 3 Sep 2024 20:32:23 +0100 Subject: Make function parameter definitions match function prototypes ( found with cppcheck) --- lib/networking/dhserver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/networking/dhserver.h b/lib/networking/dhserver.h index b0d57ac4e..6a443b220 100644 --- a/lib/networking/dhserver.h +++ b/lib/networking/dhserver.h @@ -59,7 +59,7 @@ typedef struct dhcp_config #ifdef __cplusplus extern "C" { #endif -err_t dhserv_init(const dhcp_config_t *config); +err_t dhserv_init(const dhcp_config_t *c); void dhserv_free(void); #ifdef __cplusplus } -- cgit v1.3.1 From 0bb7b992d8383e30a84d0114537ce777fb9d678e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 4 Sep 2024 20:56:04 +0700 Subject: dwc2: for esp32 force disconnect/connect using USB_WRAP otg pad override (DM=DP=0) in addition to dwc2's dctrl --- .github/actions/setup_toolchain/action.yml | 2 - .../actions/setup_toolchain/espressif/action.yml | 2 +- src/common/tusb_mcu.h | 1 + src/portable/synopsys/dwc2/dcd_dwc2.c | 24 +++++++++++- src/portable/synopsys/dwc2/dwc2_esp32.h | 44 +++++++++------------- 5 files changed, 43 insertions(+), 30 deletions(-) diff --git a/.github/actions/setup_toolchain/action.yml b/.github/actions/setup_toolchain/action.yml index d173d6903..5b9bc95ce 100644 --- a/.github/actions/setup_toolchain/action.yml +++ b/.github/actions/setup_toolchain/action.yml @@ -39,8 +39,6 @@ runs: TOOLCHAIN_JSON='{ "aarch64-gcc": "https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz", "arm-clang": "https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-17.0.1/LLVMEmbeddedToolchainForArm-17.0.1-Linux-x86_64.tar.xz", - "arm-iar": "", - "arm-gcc": "", "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz", "rx-gcc": "http://gcc-renesas.com/downloads/get.php?f=rx/8.3.0.202004-gnurx/gcc-8.3.0.202004-GNURX-ELF.run" diff --git a/.github/actions/setup_toolchain/espressif/action.yml b/.github/actions/setup_toolchain/espressif/action.yml index 3129329dd..1e3ce18f1 100644 --- a/.github/actions/setup_toolchain/espressif/action.yml +++ b/.github/actions/setup_toolchain/espressif/action.yml @@ -5,7 +5,7 @@ inputs: description: 'Toolchain name' required: true toolchain_version: - description: 'Toolchain URL or version' + description: 'Toolchain version' required: true runs: diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 52debf079..0a4462a0a 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -336,6 +336,7 @@ //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_ESP32 #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_ESP32, OPT_MCU_ESP32C2, OPT_MCU_ESP32C3, OPT_MCU_ESP32C6, OPT_MCU_ESP32H2) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 9a38b46dc..daed76105 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -43,7 +43,7 @@ #if defined(TUP_USBIP_DWC2_STM32) #include "dwc2_stm32.h" -#elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#elif defined(TUP_USBIP_DWC2_ESP32) #include "dwc2_esp32.h" #elif TU_CHECK_MCU(OPT_MCU_GD32VF103) #include "dwc2_gd32.h" @@ -667,12 +667,34 @@ void dcd_remote_wakeup(uint8_t rhport) { void dcd_connect(uint8_t rhport) { (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); + +#ifdef TUP_USBIP_DWC2_ESP32 + usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf; + conf.pad_pull_override = 0; + conf.dp_pullup = 0; + conf.dp_pulldown = 0; + conf.dm_pullup = 0; + conf.dm_pulldown = 0; + USB_WRAP.otg_conf = conf; +#endif + dwc2->dctl &= ~DCTL_SDIS; } void dcd_disconnect(uint8_t rhport) { (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); + +#ifdef TUP_USBIP_DWC2_ESP32 + usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf; + conf.pad_pull_override = 1; + conf.dp_pullup = 0; + conf.dp_pulldown = 1; + conf.dm_pullup = 0; + conf.dm_pulldown = 1; + USB_WRAP.otg_conf = conf; +#endif + dwc2->dctl |= DCTL_SDIS; } diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index 932f52f40..1a938ea46 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -32,60 +32,52 @@ extern "C" { #endif +#include "freertos/task.h" + #include "esp_intr_alloc.h" #include "soc/periph_defs.h" -//#include "soc/usb_periph.h" -#include "freertos/task.h" +#include "soc/usb_wrap_struct.h" #define DWC2_REG_BASE 0x60080000UL #define DWC2_EP_MAX 6 // USB_OUT_EP_NUM. TODO ESP32Sx only has 5 tx fifo (5 endpoint IN) -static const dwc2_controller_t _dwc2_controller[] = -{ +static const dwc2_controller_t _dwc2_controller[] = { { .reg_base = DWC2_REG_BASE, .irqnum = 0, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 1024 } }; static intr_handle_t usb_ih; -static void dcd_int_handler_wrap(void* arg) -{ - (void) arg; +static void dcd_int_handler_wrap(void* arg) { + (void)arg; dcd_int_handler(0); } -TU_ATTR_ALWAYS_INLINE -static inline void dwc2_dcd_int_enable (uint8_t rhport) -{ - (void) rhport; +TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { + (void)rhport; esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, dcd_int_handler_wrap, NULL, &usb_ih); } -TU_ATTR_ALWAYS_INLINE -static inline void dwc2_dcd_int_disable (uint8_t rhport) -{ - (void) rhport; +TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable(uint8_t rhport) { + (void)rhport; esp_intr_free(usb_ih); } -static inline void dwc2_remote_wakeup_delay(void) -{ +TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) { vTaskDelay(pdMS_TO_TICKS(1)); } // MCU specific PHY init, called BEFORE core reset -static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) -{ - (void) dwc2; - (void) hs_phy_type; +TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { + (void)dwc2; + (void)hs_phy_type; // nothing to do } // MCU specific PHY update, it is called AFTER init() and core reset -static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) -{ - (void) dwc2; - (void) hs_phy_type; +TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { + (void)dwc2; + (void)hs_phy_type; // nothing to do } @@ -94,4 +86,4 @@ static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) } #endif -#endif /* _DWC2_ESP32_H_ */ +#endif -- cgit v1.3.1 From 867f17acea98fda04fa0bf8e871f61e57044f030 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Sep 2024 10:44:22 +0700 Subject: change vendor device to use edpt stream API --- src/class/vendor/vendor_device.c | 302 ++++++++++++++++----------------------- src/common/tusb_private.h | 6 +- src/device/usbd_pvt.h | 1 + src/tusb.c | 2 +- 4 files changed, 130 insertions(+), 181 deletions(-) diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 06c663f1b..d23530235 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -45,108 +45,93 @@ typedef struct uint8_t ep_out; /*------------- From this point, data is not cleared by bus reset -------------*/ -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - tu_fifo_t rx_ff; -#endif -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - tu_fifo_t tx_ff; -#endif + // Endpoint Transfer buffer + CFG_TUD_MEM_ALIGN uint8_t epout_buf[CFG_TUD_VENDOR_EPSIZE]; + CFG_TUD_MEM_ALIGN uint8_t epin_buf[CFG_TUD_VENDOR_EPSIZE]; -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - uint8_t rx_ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; -#endif #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - uint8_t tx_ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; + struct { + tu_edpt_stream_t stream; + uint8_t ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; + }tx; #endif #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - OSAL_MUTEX_DEF(rx_ff_mutex); -#endif -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - OSAL_MUTEX_DEF(tx_ff_mutex); + struct { + tu_edpt_stream_t stream; + uint8_t ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; + } rx; #endif - // Endpoint Transfer buffer - CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_VENDOR_EPSIZE]; - CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_VENDOR_EPSIZE]; } vendord_interface_t; -CFG_TUD_MEM_SECTION tu_static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; +CFG_TUD_MEM_SECTION static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; #define ITF_MEM_RESET_SIZE offsetof(vendord_interface_t, ep_out) + sizeof(((vendord_interface_t *)0)->ep_out) - -bool tud_vendor_n_mounted (uint8_t itf) -{ +bool tud_vendor_n_mounted (uint8_t itf) { return _vendord_itf[itf].ep_in && _vendord_itf[itf].ep_out; } -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 -uint32_t tud_vendor_n_available (uint8_t itf) -{ - return tu_fifo_count(&_vendord_itf[itf].rx_ff); -} - -bool tud_vendor_n_peek(uint8_t itf, uint8_t* u8) -{ - return tu_fifo_peek(&_vendord_itf[itf].rx_ff, u8); -} -#endif - //--------------------------------------------------------------------+ // Read API //--------------------------------------------------------------------+ #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 -static void _prep_out_transaction (vendord_interface_t* p_itf) -{ - uint8_t const rhport = 0; - - // claim endpoint - TU_VERIFY(usbd_edpt_claim(rhport, p_itf->ep_out), ); +// static void _prep_out_transaction (vendord_interface_t* p_itf) +// { +// uint8_t const rhport = 0; +// +// // claim endpoint +// TU_VERIFY(usbd_edpt_claim(rhport, p_itf->ep_out), ); +// +// // Prepare for incoming data but only allow what we can store in the ring buffer. +// uint16_t max_read = tu_fifo_remaining(&p_itf->rx_ff); +// if ( max_read >= CFG_TUD_VENDOR_EPSIZE ) +// { +// usbd_edpt_xfer(rhport, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE); +// } +// else +// { +// // Release endpoint since we don't make any transfer +// usbd_edpt_release(rhport, p_itf->ep_out); +// } +// } + +uint32_t tud_vendor_n_available (uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_VENDOR, 0); + vendord_interface_t* p_itf = &_vendord_itf[itf]; + return tu_edpt_stream_read_available(&p_itf->rx.stream); +} - // Prepare for incoming data but only allow what we can store in the ring buffer. - uint16_t max_read = tu_fifo_remaining(&p_itf->rx_ff); - if ( max_read >= CFG_TUD_VENDOR_EPSIZE ) - { - usbd_edpt_xfer(rhport, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE); - } - else - { - // Release endpoint since we don't make any transfer - usbd_edpt_release(rhport, p_itf->ep_out); - } +bool tud_vendor_n_peek(uint8_t itf, uint8_t* u8) { + TU_VERIFY(itf < CFG_TUD_VENDOR, 0); + vendord_interface_t* p_itf = &_vendord_itf[itf]; + return tu_edpt_stream_peek(&p_itf->rx.stream, u8); } -uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize) -{ +uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize) { + TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; - uint32_t num_read = tu_fifo_read_n(&p_itf->rx_ff, buffer, (uint16_t) bufsize); - _prep_out_transaction(p_itf); - return num_read; + return tu_edpt_stream_read(&p_itf->rx.stream, buffer, bufsize); } -void tud_vendor_n_read_flush (uint8_t itf) -{ +void tud_vendor_n_read_flush (uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_VENDOR, ); vendord_interface_t* p_itf = &_vendord_itf[itf]; - tu_fifo_clear(&p_itf->rx_ff); - _prep_out_transaction(p_itf); + + tu_edpt_stream_clear(&p_itf->rx.stream); + tu_edpt_stream_read_xfer(&p_itf->rx.stream); } #endif //--------------------------------------------------------------------+ // Write API //--------------------------------------------------------------------+ -uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) -{ +uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) { #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 + TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; - uint16_t ret = tu_fifo_write_n(&p_itf->tx_ff, buffer, (uint16_t) bufsize); - - // flush if queue more than packet size - if (tu_fifo_count(&p_itf->tx_ff) >= CFG_TUD_VENDOR_EPSIZE) { - tud_vendor_n_write_flush(itf); - } - return ret; + return tu_edpt_stream_write(&p_itf->tx.stream, buffer, (uint16_t) bufsize); #else uint8_t const rhport = 0; vendord_interface_t* p_itf = &_vendord_itf[itf]; @@ -164,40 +149,16 @@ uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) } #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 -uint32_t tud_vendor_n_write_flush (uint8_t itf) -{ +uint32_t tud_vendor_n_write_flush (uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; - - // Skip if usb is not ready yet - TU_VERIFY( tud_ready(), 0 ); - - // No data to send - if ( !tu_fifo_count(&p_itf->tx_ff) ) return 0; - - uint8_t const rhport = 0; - - // Claim the endpoint - TU_VERIFY( usbd_edpt_claim(rhport, p_itf->ep_in), 0 ); - - // Pull data from FIFO - uint16_t const count = tu_fifo_read_n(&p_itf->tx_ff, p_itf->epin_buf, sizeof(p_itf->epin_buf)); - - if ( count ) - { - TU_ASSERT( usbd_edpt_xfer(rhport, p_itf->ep_in, p_itf->epin_buf, count), 0 ); - return count; - }else - { - // Release endpoint since we don't make any transfer - // Note: data is dropped if terminal is not connected - usbd_edpt_release(rhport, p_itf->ep_in); - return 0; - } + return tu_edpt_stream_write_xfer(&p_itf->tx.stream); } -uint32_t tud_vendor_n_write_available (uint8_t itf) -{ - return tu_fifo_remaining(&_vendord_itf[itf].tx_ff); +uint32_t tud_vendor_n_write_available (uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_VENDOR, 0); + vendord_interface_t* p_itf = &_vendord_itf[itf]; + return tu_edpt_stream_write_available(&p_itf->tx.stream); } #endif @@ -208,27 +169,19 @@ void vendord_init(void) { tu_memclr(_vendord_itf, sizeof(_vendord_itf)); for(uint8_t i=0; i 0 || CFG_TUD_VENDOR_TX_BUFSIZE > 0 vendord_interface_t* p_itf = &_vendord_itf[i]; -#endif + // config fifo #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - tu_fifo_config(&p_itf->rx_ff, p_itf->rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, 1, false); - - #if OSAL_MUTEX_REQUIRED - osal_mutex_t mutex_rd = osal_mutex_create(&p_itf->rx_ff_mutex); - TU_ASSERT(mutex_rd,); - tu_fifo_config_mutex(&p_itf->rx_ff, NULL, mutex_rd); - #endif + tu_edpt_stream_init(&p_itf->rx.stream, false, false, false, + p_itf->rx.ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, + p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE); #endif -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - tu_fifo_config(&p_itf->tx_ff, p_itf->tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, 1, false); - #if OSAL_MUTEX_REQUIRED - osal_mutex_t mutex_wr = osal_mutex_create(&p_itf->tx_ff_mutex); - TU_ASSERT(mutex_wr,); - tu_fifo_config_mutex(&p_itf->tx_ff, mutex_wr, NULL); - #endif +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 + tu_edpt_stream_init(&p_itf->tx.stream, false, true, false, + p_itf->tx.ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, + p_itf->epin_buf, CFG_TUD_VENDOR_EPSIZE); #endif } } @@ -261,37 +214,31 @@ bool vendord_deinit(void) { return true; } -void vendord_reset(uint8_t rhport) -{ +void vendord_reset(uint8_t rhport) { (void) rhport; - for(uint8_t i=0; i 0 - tu_fifo_clear(&p_itf->rx_ff); + tu_edpt_stream_clear(&p_itf->rx.stream); #endif #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - tu_fifo_clear(&p_itf->tx_ff); + tu_edpt_stream_clear(&p_itf->tx.stream); #endif } } -uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t max_len) -{ +uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t max_len) { TU_VERIFY(TUSB_CLASS_VENDOR_SPECIFIC == desc_itf->bInterfaceClass, 0); - - uint8_t const * p_desc = tu_desc_next(desc_itf); - uint8_t const * desc_end = p_desc + max_len; + const uint8_t* p_desc = tu_desc_next(desc_itf); + const uint8_t* desc_end = p_desc + max_len; // Find available interface vendord_interface_t* p_vendor = NULL; - for(uint8_t i=0; iitf_num = desc_itf->bInterfaceNumber; - if (desc_itf->bNumEndpoints) - { + uint8_t found_ep = 0; + while (found_ep < desc_itf->bNumEndpoints) { // skip non-endpoint descriptors - while ( (TUSB_DESC_ENDPOINT != tu_desc_type(p_desc)) && (p_desc < desc_end) ) - { + while ( (TUSB_DESC_ENDPOINT != tu_desc_type(p_desc)) && (p_desc < desc_end) ) { p_desc = tu_desc_next(p_desc); } + if (p_desc >= desc_end) { + break; + } - // Open endpoint pair with usbd helper - TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, desc_itf->bNumEndpoints, TUSB_XFER_BULK, &p_vendor->ep_out, &p_vendor->ep_in), 0); - - p_desc += desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); - - // Prepare for incoming data -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - _prep_out_transaction(p_vendor); -#else - if ( !usbd_edpt_xfer(rhport, p_vendor->ep_out, p_vendor->epout_buf, CFG_TUD_VENDOR_EPSIZE) ) - { - TU_LOG_FAILED(); - TU_BREAKPOINT(); + const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; + TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); + found_ep++; + + if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { + p_vendor->ep_in = desc_ep->bEndpointAddress; + + #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 + tu_edpt_stream_open(&p_vendor->tx.stream, rhport, desc_ep); + tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf)); + #endif + } else { + p_vendor->ep_out = desc_ep->bEndpointAddress; + + #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 + tu_edpt_stream_open(&p_vendor->rx.stream, rhport, desc_ep); + TU_ASSERT(tu_edpt_stream_read_xfer(&p_vendor->rx.stream) > 0, 0); // prepare for incoming data + #else + if ( !usbd_edpt_xfer(rhport, p_vendor->ep_out, p_vendor->epout_buf, CFG_TUD_VENDOR_EPSIZE) ) { + TU_LOG_FAILED(); + TU_BREAKPOINT(); + } + #endif } -#endif -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf)); -#endif + p_desc = tu_desc_next(p_desc); } return (uint16_t) ((uintptr_t) p_desc - (uintptr_t) desc_itf); } -bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ +bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + (void) rhport; (void) result; uint8_t itf = 0; vendord_interface_t* p_itf = _vendord_itf; - for ( ; ; itf++, p_itf++) - { + for ( ; ; itf++, p_itf++) { if (itf >= TU_ARRAY_SIZE(_vendord_itf)) return false; - if ( ( ep_addr == p_itf->ep_out ) || ( ep_addr == p_itf->ep_in ) ) break; } - if ( ep_addr == p_itf->ep_out ) - { + if ( ep_addr == p_itf->ep_out ) { #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - // Receive new data - tu_fifo_write_n(&p_itf->rx_ff, p_itf->epout_buf, (uint16_t) xferred_bytes); + // Receive new data, put it into stream's fifo + tu_edpt_stream_read_xfer_complete(&p_itf->rx.stream, xferred_bytes); #endif // Invoked callback if any - if (tud_vendor_rx_cb) tud_vendor_rx_cb(itf, p_itf->epout_buf, (uint16_t) xferred_bytes); + if (tud_vendor_rx_cb) { + tud_vendor_rx_cb(itf, p_itf->epout_buf, (uint16_t) xferred_bytes); + } + #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - _prep_out_transaction(p_itf); + tu_edpt_stream_read_xfer(&p_itf->rx.stream); #else TU_ASSERT(usbd_edpt_xfer(rhport, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE)); #endif - } - else if ( ep_addr == p_itf->ep_in ) - { - if (tud_vendor_tx_cb) tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); + } else if ( ep_addr == p_itf->ep_in ) { + if (tud_vendor_tx_cb) { + tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); + } #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 // Send complete, try to send more if possible - if ( 0 == tud_vendor_n_write_flush(itf) ) - { - // If there is no data left, a ZLP should be sent if - // xferred_bytes is multiple of EP Packet size and not zero - if ( !tu_fifo_count(&p_itf->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE-1))) ) - { - if ( usbd_edpt_claim(rhport, p_itf->ep_in) ) - { - usbd_edpt_xfer(rhport, p_itf->ep_in, NULL, 0); - } - } + if ( 0 == tu_edpt_stream_write_xfer(&p_itf->tx.stream) ) { + // If there is no data left, a ZLP should be sent if xferred_bytes is multiple of EP Packet size and not zero + tu_edpt_stream_write_zlp_if_needed(&p_itf->tx.stream, xferred_bytes); } #endif } diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 373a50256..5a1eb683b 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -42,10 +42,10 @@ typedef struct TU_ATTR_PACKED }tu_edpt_state_t; typedef struct { - bool is_host; // host or device most + bool is_host; // host or device union { - uint8_t daddr; - uint8_t rhport; + uint8_t daddr; // host mode + uint8_t rhport; // device mode uint8_t hwid; }; uint8_t ep_addr; diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 335d46cd8..90f37db3e 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -28,6 +28,7 @@ #include "osal/osal.h" #include "common/tusb_fifo.h" +#include "common/tusb_private.h" #ifdef __cplusplus extern "C" { diff --git a/src/tusb.c b/src/tusb.c index 860e8ac35..7b840e3a2 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -315,7 +315,7 @@ uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) { uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const* buffer, uint32_t bufsize) { TU_VERIFY(bufsize); // TODO support ZLP - uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); + const uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); // flush if fifo has more than packet size or // in rare case: fifo depth is configured too small (which never reach packet size) -- cgit v1.3.1 From c0030810dda8d9cca9cd041f246180ff03dc6624 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Sep 2024 16:15:51 +0700 Subject: update edpt_stream to support non-buffered (no fifo) mode --- src/common/tusb_private.h | 14 +++---- src/tusb.c | 102 +++++++++++++++++++++++++++++----------------- 2 files changed, 72 insertions(+), 44 deletions(-) diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 5a1eb683b..ef0d5315e 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -129,11 +129,9 @@ uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s); // Start an zero-length packet if needed bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes); -// Get the number of bytes available for writing -TU_ATTR_ALWAYS_INLINE static inline -uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) { - return (uint32_t) tu_fifo_remaining(&s->ff); -} +// Get the number of bytes available for writing to FIFO +// Note: if no fifo, return endpoint size if not busy, 0 otherwise +uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s); //--------------------------------------------------------------------+ // Stream Read @@ -148,13 +146,15 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s); // Must be called in the transfer complete callback TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_bytes) { - tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t) xferred_bytes); + if (tu_fifo_depth(&s->ff)) { + tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t) xferred_bytes); + } } // Same as tu_edpt_stream_read_xfer_complete but skip the first n bytes TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_read_xfer_complete_offset(tu_edpt_stream_t* s, uint32_t xferred_bytes, uint32_t skip_offset) { - if (skip_offset < xferred_bytes) { + if (tu_fifo_depth(&s->ff) && (skip_offset < xferred_bytes)) { tu_fifo_write_n(&s->ff, s->ep_buf + skip_offset, (uint16_t) (xferred_bytes - skip_offset)); } } diff --git a/src/tusb.c b/src/tusb.c index 7b840e3a2..44fd2dc14 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -239,8 +239,7 @@ bool tu_edpt_stream_deinit(tu_edpt_stream_t* s) { return true; } -TU_ATTR_ALWAYS_INLINE static inline -bool stream_claim(tu_edpt_stream_t* s) { +TU_ATTR_ALWAYS_INLINE static inline bool stream_claim(tu_edpt_stream_t* s) { if (s->is_host) { #if CFG_TUH_ENABLED return usbh_edpt_claim(s->daddr, s->ep_addr); @@ -253,8 +252,7 @@ bool stream_claim(tu_edpt_stream_t* s) { return false; } -TU_ATTR_ALWAYS_INLINE static inline -bool stream_xfer(tu_edpt_stream_t* s, uint16_t count) { +TU_ATTR_ALWAYS_INLINE static inline bool stream_xfer(tu_edpt_stream_t* s, uint16_t count) { if (s->is_host) { #if CFG_TUH_ENABLED return usbh_edpt_xfer(s->daddr, s->ep_addr, count ? s->ep_buf : NULL, count); @@ -267,8 +265,7 @@ bool stream_xfer(tu_edpt_stream_t* s, uint16_t count) { return false; } -TU_ATTR_ALWAYS_INLINE static inline -bool stream_release(tu_edpt_stream_t* s) { +TU_ATTR_ALWAYS_INLINE static inline bool stream_release(tu_edpt_stream_t* s) { if (s->is_host) { #if CFG_TUH_ENABLED return usbh_edpt_release(s->daddr, s->ep_addr); @@ -296,7 +293,6 @@ uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) { // skip if no data TU_VERIFY(tu_fifo_count(&s->ff), 0); - // Claim the endpoint TU_VERIFY(stream_claim(s), 0); // Pull data from FIFO -> EP buf @@ -315,46 +311,78 @@ uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) { uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const* buffer, uint32_t bufsize) { TU_VERIFY(bufsize); // TODO support ZLP - const uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); - // flush if fifo has more than packet size or - // in rare case: fifo depth is configured too small (which never reach packet size) - if ((tu_fifo_count(&s->ff) >= s->ep_packetsize) || (tu_fifo_depth(&s->ff) < s->ep_packetsize)) { - tu_edpt_stream_write_xfer(s); + if (0 == tu_fifo_depth(&s->ff)) { + // no fifo for buffered + TU_VERIFY(stream_claim(s), 0); + const uint32_t xact_len = tu_min32(bufsize, s->ep_bufsize); + memcpy(s->ep_buf, buffer, xact_len); + TU_ASSERT(stream_xfer(s, xact_len), 0); + return xact_len; + } else { + const uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); + + // flush if fifo has more than packet size or + // in rare case: fifo depth is configured too small (which never reach packet size) + if ((tu_fifo_count(&s->ff) >= s->ep_packetsize) || (tu_fifo_depth(&s->ff) < s->ep_packetsize)) { + tu_edpt_stream_write_xfer(s); + } + return ret; } +} - return ret; +uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) { + if (tu_fifo_depth(&s->ff)) { + return (uint32_t) tu_fifo_remaining(&s->ff); + } else { + bool is_busy = true; + if (s->is_host) { + #if CFG_TUH_ENABLED + is_busy = usbh_edpt_busy(s->daddr, s->ep_addr); + #endif + } else { + #if CFG_TUD_ENABLED + is_busy = usbd_edpt_busy(s->rhport, s->ep_addr); + #endif + } + return is_busy ? 0 : s->ep_bufsize; + } } //--------------------------------------------------------------------+ // Stream Read //--------------------------------------------------------------------+ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) { - uint16_t available = tu_fifo_remaining(&s->ff); - - // Prepare for incoming data but only allow what we can store in the ring buffer. - // TODO Actually we can still carry out the transfer, keeping count of received bytes - // and slowly move it to the FIFO when read(). - // This pre-check reduces endpoint claiming - TU_VERIFY(available >= s->ep_packetsize); - - // claim endpoint - TU_VERIFY(stream_claim(s), 0); - - // get available again since fifo can be changed before endpoint is claimed - available = tu_fifo_remaining(&s->ff); - - if (available >= s->ep_packetsize) { - // multiple of packet size limit by ep bufsize - uint16_t count = (uint16_t) (available & ~(s->ep_packetsize - 1)); - count = tu_min16(count, s->ep_bufsize); - - TU_ASSERT(stream_xfer(s, count), 0); - return count; + if (0 == tu_fifo_depth(&s->ff)) { + // no fifo for buffered + TU_VERIFY(stream_claim(s), 0); + TU_ASSERT(stream_xfer(s, s->ep_bufsize), 0); + return s->ep_bufsize; } else { - // Release endpoint since we don't make any transfer - stream_release(s); - return 0; + uint16_t available = tu_fifo_remaining(&s->ff); + + // Prepare for incoming data but only allow what we can store in the ring buffer. + // TODO Actually we can still carry out the transfer, keeping count of received bytes + // and slowly move it to the FIFO when read(). + // This pre-check reduces endpoint claiming + TU_VERIFY(available >= s->ep_packetsize); + + TU_VERIFY(stream_claim(s), 0); + + // get available again since fifo can be changed before endpoint is claimed + available = tu_fifo_remaining(&s->ff); + + if (available >= s->ep_packetsize) { + // multiple of packet size limit by ep bufsize + uint16_t count = (uint16_t) (available & ~(s->ep_packetsize - 1)); + count = tu_min16(count, s->ep_bufsize); + TU_ASSERT(stream_xfer(s, count), 0); + return count; + } else { + // Release endpoint since we don't make any transfer + stream_release(s); + return 0; + } } } -- cgit v1.3.1 From cc816dc9c04762f14468a0b7b1826768e731f53f Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Sep 2024 17:41:20 +0700 Subject: change edpt stream api to take hwid from API to reduce memory footprint --- src/class/cdc/cdc_host.c | 22 ++++++++--------- src/common/tusb_private.h | 25 ++++++++----------- src/tusb.c | 62 +++++++++++++++++++++++------------------------ 3 files changed, 52 insertions(+), 57 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 133a10f6e..8717970e6 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -341,14 +341,14 @@ uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write(&p_cdc->stream.tx, buffer, bufsize); + return tu_edpt_stream_write(p_cdc->daddr, &p_cdc->stream.tx, buffer, bufsize); } uint32_t tuh_cdc_write_flush(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write_xfer(&p_cdc->stream.tx); + return tu_edpt_stream_write_xfer(p_cdc->daddr, &p_cdc->stream.tx); } bool tuh_cdc_write_clear(uint8_t idx) { @@ -362,7 +362,7 @@ uint32_t tuh_cdc_write_available(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write_available(&p_cdc->stream.tx); + return tu_edpt_stream_write_available(p_cdc->daddr, &p_cdc->stream.tx); } //--------------------------------------------------------------------+ @@ -373,7 +373,7 @@ uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_read(&p_cdc->stream.rx, buffer, bufsize); + return tu_edpt_stream_read(p_cdc->daddr, &p_cdc->stream.rx, buffer, bufsize); } uint32_t tuh_cdc_read_available(uint8_t idx) { @@ -395,7 +395,7 @@ bool tuh_cdc_read_clear (uint8_t idx) { TU_VERIFY(p_cdc); bool ret = tu_edpt_stream_clear(&p_cdc->stream.rx); - tu_edpt_stream_read_xfer(&p_cdc->stream.rx); + tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); return ret; } @@ -677,10 +677,10 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t // invoke tx complete callback to possibly refill tx fifo if (tuh_cdc_tx_complete_cb) tuh_cdc_tx_complete_cb(idx); - if ( 0 == tu_edpt_stream_write_xfer(&p_cdc->stream.tx) ) { + if ( 0 == tu_edpt_stream_write_xfer(daddr, &p_cdc->stream.tx) ) { // If there is no data left, a ZLP should be sent if: // - xferred_bytes is multiple of EP Packet size and not zero - tu_edpt_stream_write_zlp_if_needed(&p_cdc->stream.tx, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(daddr, &p_cdc->stream.tx, xferred_bytes); } } else if ( ep_addr == p_cdc->stream.rx.ep_addr ) { #if CFG_TUH_CDC_FTDI @@ -698,7 +698,7 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t if (tuh_cdc_rx_cb) tuh_cdc_rx_cb(idx); // prepare for next transfer if needed - tu_edpt_stream_read_xfer(&p_cdc->stream.rx); + tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx); }else if ( ep_addr == p_cdc->ep_notif ) { // TODO handle notification endpoint }else { @@ -719,9 +719,9 @@ static bool open_ep_stream_pair(cdch_interface_t* p_cdc, tusb_desc_endpoint_t co TU_ASSERT(tuh_edpt_open(p_cdc->daddr, desc_ep)); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { - tu_edpt_stream_open(&p_cdc->stream.rx, p_cdc->daddr, desc_ep); + tu_edpt_stream_open(&p_cdc->stream.rx, desc_ep); } else { - tu_edpt_stream_open(&p_cdc->stream.tx, p_cdc->daddr, desc_ep); + tu_edpt_stream_open(&p_cdc->stream.tx, desc_ep); } desc_ep = (tusb_desc_endpoint_t const*) tu_desc_next(desc_ep); @@ -763,7 +763,7 @@ static void set_config_complete(cdch_interface_t * p_cdc, uint8_t idx, uint8_t i if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(idx); // Prepare for incoming data - tu_edpt_stream_read_xfer(&p_cdc->stream.rx); + tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); // notify usbh that driver enumeration is complete usbh_driver_set_config_complete(p_cdc->daddr, itf_num); diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index ef0d5315e..71a395c79 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -42,14 +42,11 @@ typedef struct TU_ATTR_PACKED }tu_edpt_state_t; typedef struct { - bool is_host; // host or device - union { - uint8_t daddr; // host mode - uint8_t rhport; // device mode - uint8_t hwid; + struct { + uint8_t is_host : 1; // host or device + uint8_t is_highspeed: 1; // is highspeed }; uint8_t ep_addr; - uint8_t ep_speed; uint16_t ep_packetsize; uint16_t ep_bufsize; @@ -97,16 +94,14 @@ bool tu_edpt_stream_deinit(tu_edpt_stream_t* s); // Open an stream for an endpoint // hwid is either device address (host mode) or rhport (device mode) TU_ATTR_ALWAYS_INLINE static inline -void tu_edpt_stream_open(tu_edpt_stream_t* s, uint8_t hwid, tusb_desc_endpoint_t const *desc_ep) { +void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) { tu_fifo_clear(&s->ff); - s->hwid = hwid; s->ep_addr = desc_ep->bEndpointAddress; s->ep_packetsize = tu_edpt_packet_size(desc_ep); } TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_close(tu_edpt_stream_t* s) { - s->hwid = 0; s->ep_addr = 0; } @@ -121,27 +116,27 @@ bool tu_edpt_stream_clear(tu_edpt_stream_t* s) { //--------------------------------------------------------------------+ // Write to stream -uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize); +uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize); // Start an usb transfer if endpoint is not busy -uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s); +uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s); // Start an zero-length packet if needed -bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes); +bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes); // Get the number of bytes available for writing to FIFO // Note: if no fifo, return endpoint size if not busy, 0 otherwise -uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s); +uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t* s); //--------------------------------------------------------------------+ // Stream Read //--------------------------------------------------------------------+ // Read from stream -uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize); +uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize); // Start an usb transfer if endpoint is not busy -uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s); +uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s); // Must be called in the transfer complete callback TU_ATTR_ALWAYS_INLINE static inline diff --git a/src/tusb.c b/src/tusb.c index 44fd2dc14..69c1f9775 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -239,40 +239,40 @@ bool tu_edpt_stream_deinit(tu_edpt_stream_t* s) { return true; } -TU_ATTR_ALWAYS_INLINE static inline bool stream_claim(tu_edpt_stream_t* s) { +TU_ATTR_ALWAYS_INLINE static inline bool stream_claim(uint8_t hwid, tu_edpt_stream_t* s) { if (s->is_host) { #if CFG_TUH_ENABLED - return usbh_edpt_claim(s->daddr, s->ep_addr); + return usbh_edpt_claim(hwid, s->ep_addr); #endif } else { #if CFG_TUD_ENABLED - return usbd_edpt_claim(s->rhport, s->ep_addr); + return usbd_edpt_claim(hwid, s->ep_addr); #endif } return false; } -TU_ATTR_ALWAYS_INLINE static inline bool stream_xfer(tu_edpt_stream_t* s, uint16_t count) { +TU_ATTR_ALWAYS_INLINE static inline bool stream_xfer(uint8_t hwid, tu_edpt_stream_t* s, uint16_t count) { if (s->is_host) { #if CFG_TUH_ENABLED - return usbh_edpt_xfer(s->daddr, s->ep_addr, count ? s->ep_buf : NULL, count); + return usbh_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count); #endif } else { #if CFG_TUD_ENABLED - return usbd_edpt_xfer(s->rhport, s->ep_addr, count ? s->ep_buf : NULL, count); + return usbd_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count); #endif } return false; } -TU_ATTR_ALWAYS_INLINE static inline bool stream_release(tu_edpt_stream_t* s) { +TU_ATTR_ALWAYS_INLINE static inline bool stream_release(uint8_t hwid, tu_edpt_stream_t* s) { if (s->is_host) { #if CFG_TUH_ENABLED - return usbh_edpt_release(s->daddr, s->ep_addr); + return usbh_edpt_release(hwid, s->ep_addr); #endif } else { #if CFG_TUD_ENABLED - return usbd_edpt_release(s->rhport, s->ep_addr); + return usbd_edpt_release(hwid, s->ep_addr); #endif } return false; @@ -281,43 +281,43 @@ TU_ATTR_ALWAYS_INLINE static inline bool stream_release(tu_edpt_stream_t* s) { //--------------------------------------------------------------------+ // Stream Write //--------------------------------------------------------------------+ -bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes) { +bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes) { // ZLP condition: no pending data, last transferred bytes is multiple of packet size TU_VERIFY(!tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (s->ep_packetsize - 1)))); - TU_VERIFY(stream_claim(s)); - TU_ASSERT(stream_xfer(s, 0)); + TU_VERIFY(stream_claim(hwid, s)); + TU_ASSERT(stream_xfer(hwid, s, 0)); return true; } -uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) { +uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) { // skip if no data TU_VERIFY(tu_fifo_count(&s->ff), 0); - TU_VERIFY(stream_claim(s), 0); + TU_VERIFY(stream_claim(hwid, s), 0); // Pull data from FIFO -> EP buf uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); if (count) { - TU_ASSERT(stream_xfer(s, count), 0); + TU_ASSERT(stream_xfer(hwid, s, count), 0); return count; } else { // Release endpoint since we don't make any transfer // Note: data is dropped if terminal is not connected - stream_release(s); + stream_release(hwid, s); return 0; } } -uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const* buffer, uint32_t bufsize) { +uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const* buffer, uint32_t bufsize) { TU_VERIFY(bufsize); // TODO support ZLP if (0 == tu_fifo_depth(&s->ff)) { // no fifo for buffered - TU_VERIFY(stream_claim(s), 0); + TU_VERIFY(stream_claim(hwid, s), 0); const uint32_t xact_len = tu_min32(bufsize, s->ep_bufsize); memcpy(s->ep_buf, buffer, xact_len); - TU_ASSERT(stream_xfer(s, xact_len), 0); + TU_ASSERT(stream_xfer(hwid, s, xact_len), 0); return xact_len; } else { const uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); @@ -325,24 +325,24 @@ uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const* buffer, uint32_t // flush if fifo has more than packet size or // in rare case: fifo depth is configured too small (which never reach packet size) if ((tu_fifo_count(&s->ff) >= s->ep_packetsize) || (tu_fifo_depth(&s->ff) < s->ep_packetsize)) { - tu_edpt_stream_write_xfer(s); + tu_edpt_stream_write_xfer(hwid, s); } return ret; } } -uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) { +uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t* s) { if (tu_fifo_depth(&s->ff)) { return (uint32_t) tu_fifo_remaining(&s->ff); } else { bool is_busy = true; if (s->is_host) { #if CFG_TUH_ENABLED - is_busy = usbh_edpt_busy(s->daddr, s->ep_addr); + is_busy = usbh_edpt_busy(hwid, s->ep_addr); #endif } else { #if CFG_TUD_ENABLED - is_busy = usbd_edpt_busy(s->rhport, s->ep_addr); + is_busy = usbd_edpt_busy(hwid, s->ep_addr); #endif } return is_busy ? 0 : s->ep_bufsize; @@ -352,11 +352,11 @@ uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) { //--------------------------------------------------------------------+ // Stream Read //--------------------------------------------------------------------+ -uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) { +uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s) { if (0 == tu_fifo_depth(&s->ff)) { // no fifo for buffered - TU_VERIFY(stream_claim(s), 0); - TU_ASSERT(stream_xfer(s, s->ep_bufsize), 0); + TU_VERIFY(stream_claim(hwid, s), 0); + TU_ASSERT(stream_xfer(hwid, s, s->ep_bufsize), 0); return s->ep_bufsize; } else { uint16_t available = tu_fifo_remaining(&s->ff); @@ -367,7 +367,7 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) { // This pre-check reduces endpoint claiming TU_VERIFY(available >= s->ep_packetsize); - TU_VERIFY(stream_claim(s), 0); + TU_VERIFY(stream_claim(hwid, s), 0); // get available again since fifo can be changed before endpoint is claimed available = tu_fifo_remaining(&s->ff); @@ -376,19 +376,19 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) { // multiple of packet size limit by ep bufsize uint16_t count = (uint16_t) (available & ~(s->ep_packetsize - 1)); count = tu_min16(count, s->ep_bufsize); - TU_ASSERT(stream_xfer(s, count), 0); + TU_ASSERT(stream_xfer(hwid, s, count), 0); return count; } else { // Release endpoint since we don't make any transfer - stream_release(s); + stream_release(hwid, s); return 0; } } } -uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize) { +uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize) { uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t) bufsize); - tu_edpt_stream_read_xfer(s); + tu_edpt_stream_read_xfer(hwid, s); return num_read; } -- cgit v1.3.1 From bbeae09259707ba6b79db55dda2fd89b9e99f14f Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Sep 2024 17:45:03 +0700 Subject: update vendor device to use edpt stream which also support non-buffereed (no fifo) mode --- src/class/vendor/vendor_device.c | 170 +++++++++++++-------------------------- src/class/vendor/vendor_device.h | 117 ++++++++++----------------- 2 files changed, 101 insertions(+), 186 deletions(-) diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index d23530235..5d33d2e60 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -38,8 +38,7 @@ //--------------------------------------------------------------------+ #define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -typedef struct -{ +typedef struct { uint8_t itf_num; uint8_t ep_in; uint8_t ep_out; @@ -49,19 +48,19 @@ typedef struct CFG_TUD_MEM_ALIGN uint8_t epout_buf[CFG_TUD_VENDOR_EPSIZE]; CFG_TUD_MEM_ALIGN uint8_t epin_buf[CFG_TUD_VENDOR_EPSIZE]; -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 struct { tu_edpt_stream_t stream; + #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 uint8_t ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; + #endif }tx; -#endif -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 struct { tu_edpt_stream_t stream; + #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 uint8_t ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; + #endif } rx; -#endif } vendord_interface_t; @@ -69,6 +68,10 @@ CFG_TUD_MEM_SECTION static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; #define ITF_MEM_RESET_SIZE offsetof(vendord_interface_t, ep_out) + sizeof(((vendord_interface_t *)0)->ep_out) +//-------------------------------------------------------------------- +// Application API +//-------------------------------------------------------------------- + bool tud_vendor_n_mounted (uint8_t itf) { return _vendord_itf[itf].ep_in && _vendord_itf[itf].ep_out; } @@ -76,91 +79,63 @@ bool tud_vendor_n_mounted (uint8_t itf) { //--------------------------------------------------------------------+ // Read API //--------------------------------------------------------------------+ -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 -// static void _prep_out_transaction (vendord_interface_t* p_itf) -// { -// uint8_t const rhport = 0; -// -// // claim endpoint -// TU_VERIFY(usbd_edpt_claim(rhport, p_itf->ep_out), ); -// -// // Prepare for incoming data but only allow what we can store in the ring buffer. -// uint16_t max_read = tu_fifo_remaining(&p_itf->rx_ff); -// if ( max_read >= CFG_TUD_VENDOR_EPSIZE ) -// { -// usbd_edpt_xfer(rhport, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE); -// } -// else -// { -// // Release endpoint since we don't make any transfer -// usbd_edpt_release(rhport, p_itf->ep_out); -// } -// } - uint32_t tud_vendor_n_available (uint8_t itf) { TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; + return tu_edpt_stream_read_available(&p_itf->rx.stream); } bool tud_vendor_n_peek(uint8_t itf, uint8_t* u8) { TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; + return tu_edpt_stream_peek(&p_itf->rx.stream, u8); } uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize) { TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; - return tu_edpt_stream_read(&p_itf->rx.stream, buffer, bufsize); + uint8_t const rhport = 0; + + return tu_edpt_stream_read(rhport, &p_itf->rx.stream, buffer, bufsize); } void tud_vendor_n_read_flush (uint8_t itf) { TU_VERIFY(itf < CFG_TUD_VENDOR, ); vendord_interface_t* p_itf = &_vendord_itf[itf]; + uint8_t const rhport = 0; tu_edpt_stream_clear(&p_itf->rx.stream); - tu_edpt_stream_read_xfer(&p_itf->rx.stream); + tu_edpt_stream_read_xfer(rhport, &p_itf->rx.stream); } -#endif //--------------------------------------------------------------------+ // Write API //--------------------------------------------------------------------+ uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) { -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; - return tu_edpt_stream_write(&p_itf->tx.stream, buffer, (uint16_t) bufsize); -#else uint8_t const rhport = 0; - vendord_interface_t* p_itf = &_vendord_itf[itf]; - // claim endpoint - TU_VERIFY(usbd_edpt_claim(rhport, p_itf->ep_in)); - - // prepare data - TU_VERIFY(0 == tu_memcpy_s(p_itf->epin_buf, CFG_TUD_VENDOR_EPSIZE, buffer, (uint16_t) bufsize)); - - TU_ASSERT(usbd_edpt_xfer(rhport, p_itf->ep_in, p_itf->epin_buf, (uint16_t) bufsize)); - - return bufsize; -#endif + return tu_edpt_stream_write(rhport, &p_itf->tx.stream, buffer, (uint16_t) bufsize); } -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 uint32_t tud_vendor_n_write_flush (uint8_t itf) { TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; - return tu_edpt_stream_write_xfer(&p_itf->tx.stream); + uint8_t const rhport = 0; + + return tu_edpt_stream_write_xfer(rhport, &p_itf->tx.stream); } uint32_t tud_vendor_n_write_available (uint8_t itf) { TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; - return tu_edpt_stream_write_available(&p_itf->tx.stream); + uint8_t const rhport = 0; + + return tu_edpt_stream_write_available(rhport, &p_itf->tx.stream); } -#endif //--------------------------------------------------------------------+ // USBD Driver API @@ -171,46 +146,36 @@ void vendord_init(void) { for(uint8_t i=0; i 0 + uint8_t* rx_ff_buf = + #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 + p_itf->rx.ff_buf; + #else + NULL; + #endif + tu_edpt_stream_init(&p_itf->rx.stream, false, false, false, - p_itf->rx.ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, + rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE); -#endif -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 + uint8_t* tx_ff_buf = + #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 + p_itf->tx.ff_buf; + #else + NULL; + #endif + tu_edpt_stream_init(&p_itf->tx.stream, false, true, false, - p_itf->tx.ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, + tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, p_itf->epin_buf, CFG_TUD_VENDOR_EPSIZE); -#endif } } bool vendord_deinit(void) { -#if OSAL_MUTEX_REQUIRED - #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 for(uint8_t i=0; irx_ff.mutex_rd; - - if (mutex_rd) { - osal_mutex_delete(mutex_rd); - tu_fifo_config_mutex(&p_itf->rx_ff, NULL, NULL); - } + tu_edpt_stream_deinit(&p_itf->rx.stream); + tu_edpt_stream_deinit(&p_itf->tx.stream); } - #endif - #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - for(uint8_t i=0; itx_ff.mutex_wr; - - if (mutex_wr) { - osal_mutex_delete(mutex_wr); - tu_fifo_config_mutex(&p_itf->tx_ff, NULL, NULL); - } - } - #endif -#endif return true; } @@ -219,14 +184,9 @@ void vendord_reset(uint8_t rhport) { for(uint8_t i=0; i 0 tu_edpt_stream_clear(&p_itf->rx.stream); -#endif -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 tu_edpt_stream_clear(&p_itf->tx.stream); -#endif } } @@ -262,23 +222,12 @@ uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, ui if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { p_vendor->ep_in = desc_ep->bEndpointAddress; - - #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - tu_edpt_stream_open(&p_vendor->tx.stream, rhport, desc_ep); + tu_edpt_stream_open(&p_vendor->tx.stream, desc_ep); tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf)); - #endif } else { p_vendor->ep_out = desc_ep->bEndpointAddress; - - #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - tu_edpt_stream_open(&p_vendor->rx.stream, rhport, desc_ep); - TU_ASSERT(tu_edpt_stream_read_xfer(&p_vendor->rx.stream) > 0, 0); // prepare for incoming data - #else - if ( !usbd_edpt_xfer(rhport, p_vendor->ep_out, p_vendor->epout_buf, CFG_TUD_VENDOR_EPSIZE) ) { - TU_LOG_FAILED(); - TU_BREAKPOINT(); - } - #endif + tu_edpt_stream_open(&p_vendor->rx.stream, desc_ep); + TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_vendor->rx.stream) > 0, 0); // prepare for incoming data } p_desc = tu_desc_next(p_desc); @@ -288,44 +237,39 @@ uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, ui } bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - (void) rhport; (void) result; uint8_t itf = 0; vendord_interface_t* p_itf = _vendord_itf; for ( ; ; itf++, p_itf++) { - if (itf >= TU_ARRAY_SIZE(_vendord_itf)) return false; - if ( ( ep_addr == p_itf->ep_out ) || ( ep_addr == p_itf->ep_in ) ) break; + if (itf >= CFG_TUD_VENDOR) return false; + if ((ep_addr == p_itf->rx.stream.ep_addr) || (ep_addr == p_itf->tx.stream.ep_addr)) break; } - if ( ep_addr == p_itf->ep_out ) { -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - // Receive new data, put it into stream's fifo + if ( ep_addr == p_itf->rx.stream.ep_addr ) { + // Received new data: put into stream's fifo tu_edpt_stream_read_xfer_complete(&p_itf->rx.stream, xferred_bytes); -#endif // Invoked callback if any if (tud_vendor_rx_cb) { tud_vendor_rx_cb(itf, p_itf->epout_buf, (uint16_t) xferred_bytes); } -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - tu_edpt_stream_read_xfer(&p_itf->rx.stream); -#else - TU_ASSERT(usbd_edpt_xfer(rhport, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE)); -#endif - } else if ( ep_addr == p_itf->ep_in ) { + tu_edpt_stream_read_xfer(rhport, &p_itf->rx.stream); + } else if ( ep_addr == p_itf->tx.stream.ep_addr ) { + // Send complete if (tud_vendor_tx_cb) { tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); } -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - // Send complete, try to send more if possible - if ( 0 == tu_edpt_stream_write_xfer(&p_itf->tx.stream) ) { + + #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 + // try to send more if possible + if ( 0 == tu_edpt_stream_write_xfer(rhport, &p_itf->tx.stream) ) { // If there is no data left, a ZLP should be sent if xferred_bytes is multiple of EP Packet size and not zero - tu_edpt_stream_write_zlp_if_needed(&p_itf->tx.stream, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(rhport, &p_itf->tx.stream, xferred_bytes); } -#endif + #endif } return true; diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index 4a0cc3151..149ae2d56 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -33,12 +33,12 @@ #define CFG_TUD_VENDOR_EPSIZE 64 #endif -/* RX FIFO can be disabled by setting this value to 0, related API will also be disabled */ +// RX FIFO can be disabled by setting this value to 0 #ifndef CFG_TUD_VENDOR_RX_BUFSIZE #define CFG_TUD_VENDOR_RX_BUFSIZE 64 #endif -/* TX FIFO can be disabled by setting this value to 0, related API will also be disabled */ +// TX FIFO can be disabled by setting this value to 0 #ifndef CFG_TUD_VENDOR_TX_BUFSIZE #define CFG_TUD_VENDOR_TX_BUFSIZE 64 #endif @@ -48,115 +48,86 @@ #endif //--------------------------------------------------------------------+ -// Application API (Multiple Interfaces) +// Application API (Multiple Interfaces) i.e CFG_TUD_VENDOR > 1 //--------------------------------------------------------------------+ bool tud_vendor_n_mounted (uint8_t itf); - -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 uint32_t tud_vendor_n_available (uint8_t itf); uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize); bool tud_vendor_n_peek (uint8_t itf, uint8_t* ui8); void tud_vendor_n_read_flush (uint8_t itf); -#endif uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 uint32_t tud_vendor_n_write_flush (uint8_t itf); uint32_t tud_vendor_n_write_available (uint8_t itf); -#endif -static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 -// backward compatible -#define tud_vendor_n_flush(itf) tud_vendor_n_write_flush(itf) -#endif - -//--------------------------------------------------------------------+ -// Application API (Single Port) -//--------------------------------------------------------------------+ -static inline bool tud_vendor_mounted (void); -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 -static inline uint32_t tud_vendor_available (void); -static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize); -static inline bool tud_vendor_peek (uint8_t* ui8); -static inline void tud_vendor_read_flush (void); -#endif -static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize); -static inline uint32_t tud_vendor_write_str (char const* str); -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 -static inline uint32_t tud_vendor_write_available (void); -static inline uint32_t tud_vendor_write_flush (void); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); // backward compatible -#define tud_vendor_flush() tud_vendor_write_flush() -#endif -//--------------------------------------------------------------------+ -// Application Callback API (weak is optional) -//--------------------------------------------------------------------+ - -// Invoked when received new data -TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t itf, uint8_t const* buffer, uint16_t bufsize); -// Invoked when last rx transfer finished -TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes); +#define tud_vendor_n_flush(itf) tud_vendor_n_write_flush(itf) //--------------------------------------------------------------------+ -// Inline Functions +// Application API (Single Port) i.e CFG_TUD_VENDOR = 1 //--------------------------------------------------------------------+ -static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str) -{ - return tud_vendor_n_write(itf, str, strlen(str)); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_n_write_str(uint8_t itf, char const* str) { + return tud_vendor_n_write(itf, str, strlen(str)); } -static inline bool tud_vendor_mounted (void) -{ - return tud_vendor_n_mounted(0); +TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_mounted(void) { + return tud_vendor_n_mounted(0); } -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 -static inline uint32_t tud_vendor_available (void) -{ - return tud_vendor_n_available(0); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_available(void) { + return tud_vendor_n_available(0); } -static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize) -{ - return tud_vendor_n_read(0, buffer, bufsize); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_read(void* buffer, uint32_t bufsize) { + return tud_vendor_n_read(0, buffer, bufsize); } -static inline bool tud_vendor_peek (uint8_t* ui8) -{ - return tud_vendor_n_peek(0, ui8); +TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_peek(uint8_t* ui8) { + return tud_vendor_n_peek(0, ui8); } -static inline void tud_vendor_read_flush(void) -{ - tud_vendor_n_read_flush(0); +TU_ATTR_ALWAYS_INLINE static inline void tud_vendor_read_flush(void) { + tud_vendor_n_read_flush(0); } -#endif -static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize) -{ - return tud_vendor_n_write(0, buffer, bufsize); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write(void const* buffer, uint32_t bufsize) { + return tud_vendor_n_write(0, buffer, bufsize); } -static inline uint32_t tud_vendor_write_str (char const* str) -{ - return tud_vendor_n_write_str(0, str); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_str(char const* str) { + return tud_vendor_n_write_str(0, str); } -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 -static inline uint32_t tud_vendor_write_flush (void) -{ - return tud_vendor_n_write_flush(0); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_flush(void) { + return tud_vendor_n_write_flush(0); } -static inline uint32_t tud_vendor_write_available (void) -{ - return tud_vendor_n_write_available(0); +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_available(void) { + return tud_vendor_n_write_available(0); } #endif +// backward compatible +#define tud_vendor_flush() tud_vendor_write_flush() + +//--------------------------------------------------------------------+ +// Application Callback API (weak is optional) +//--------------------------------------------------------------------+ + +// Invoked when received new data +TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t itf, uint8_t const* buffer, uint16_t bufsize); +// Invoked when last rx transfer finished +TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes); + +//--------------------------------------------------------------------+ +// Inline Functions +//--------------------------------------------------------------------+ + + //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -- cgit v1.3.1 From 7373a0239645b48bbd1c11e9542699924e1f3a0d Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Sep 2024 18:13:38 +0700 Subject: minor clean up --- examples/device/webusb_serial/src/main.c | 124 +++++++++--------------- examples/device/webusb_serial/src/tusb_config.h | 2 +- src/common/tusb_private.h | 14 +-- 3 files changed, 51 insertions(+), 89 deletions(-) diff --git a/examples/device/webusb_serial/src/main.c b/examples/device/webusb_serial/src/main.c index 800d435b8..bcc33f657 100644 --- a/examples/device/webusb_serial/src/main.c +++ b/examples/device/webusb_serial/src/main.c @@ -73,8 +73,7 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; #define URL "example.tinyusb.org/webusb-serial/index.html" -const tusb_desc_webusb_url_t desc_url = -{ +const tusb_desc_webusb_url_t desc_url = { .bLength = 3 + sizeof(URL) - 1, .bDescriptorType = 3, // WEBUSB URL type .bScheme = 1, // 0: http, 1: https @@ -86,11 +85,9 @@ static bool web_serial_connected = false; //------------- prototypes -------------// void led_blinking_task(void); void cdc_task(void); -void webserial_task(void); /*------------- MAIN -------------*/ -int main(void) -{ +int main(void) { board_init(); // init device stack on configured roothub port @@ -100,33 +97,28 @@ int main(void) board_init_after_tusb(); } - while (1) - { + while (1) { tud_task(); // tinyusb device task cdc_task(); - webserial_task(); led_blinking_task(); } } // send characters to both CDC and WebUSB -void echo_all(uint8_t buf[], uint32_t count) -{ +void echo_all(const uint8_t buf[], uint32_t count) { // echo to web serial - if ( web_serial_connected ) - { + if (web_serial_connected) { tud_vendor_write(buf, count); tud_vendor_write_flush(); } // echo to cdc - if ( tud_cdc_connected() ) - { - for(uint32_t i=0; ibmRequestType_bit.type) - { + switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_VENDOR: - switch (request->bRequest) - { + switch (request->bRequest) { case VENDOR_REQUEST_WEBUSB: // match vendor request in BOS descriptor // Get landing page url - return tud_control_xfer(rhport, request, (void*)(uintptr_t) &desc_url, desc_url.bLength); + return tud_control_xfer(rhport, request, (void*)(uintptr_t)&desc_url, desc_url.bLength); case VENDOR_REQUEST_MICROSOFT: - if ( request->wIndex == 7 ) - { + if (request->wIndex == 7) { // Get Microsoft OS 2.0 compatible descriptor uint16_t total_len; - memcpy(&total_len, desc_ms_os_20+8, 2); + memcpy(&total_len, desc_ms_os_20 + 8, 2); - return tud_control_xfer(rhport, request, (void*)(uintptr_t) desc_ms_os_20, total_len); - }else - { + return tud_control_xfer(rhport, request, (void*)(uintptr_t)desc_ms_os_20, total_len); + } else { return false; } default: break; } - break; + break; case TUSB_REQ_TYPE_CLASS: - if (request->bRequest == 0x22) - { + if (request->bRequest == 0x22) { // Webserial simulate the CDC_REQUEST_SET_CONTROL_LINE_STATE (0x22) to connect and disconnect. web_serial_connected = (request->wValue != 0); // Always lit LED if connected - if ( web_serial_connected ) - { + if (web_serial_connected) { board_led_write(true); blink_interval_ms = BLINK_ALWAYS_ON; tud_vendor_write_str("\r\nWebUSB interface connected\r\n"); tud_vendor_write_flush(); - }else - { + } else { blink_interval_ms = BLINK_MOUNTED; } // response with status OK return tud_control_status(rhport, request); } - break; + break; default: break; } @@ -233,32 +213,24 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ return false; } -void webserial_task(void) -{ - if ( web_serial_connected ) - { - if ( tud_vendor_available() ) - { - uint8_t buf[64]; - uint32_t count = tud_vendor_read(buf, sizeof(buf)); +void tud_vendor_rx_cb(uint8_t itf, uint8_t const* buffer, uint16_t bufsize) { + (void) itf; - // echo back to both web serial and cdc - echo_all(buf, count); - } - } -} + echo_all(buffer, bufsize); + // if using RX buffered is enabled, we need to flush the buffer to make room for new data + #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 + tud_vendor_read_flush(); + #endif +} //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ -void cdc_task(void) -{ - if ( tud_cdc_connected() ) - { +void cdc_task(void) { + if (tud_cdc_connected()) { // connected and there are data available - if ( tud_cdc_available() ) - { + if (tud_cdc_available()) { uint8_t buf[64]; uint32_t count = tud_cdc_read(buf, sizeof(buf)); @@ -270,34 +242,30 @@ void cdc_task(void) } // Invoked when cdc when line state changed e.g connected/disconnected -void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) -{ - (void) itf; +void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { + (void)itf; // connected - if ( dtr && rts ) - { + if (dtr && rts) { // print initial message when connected tud_cdc_write_str("\r\nTinyUSB WebUSB device example\r\n"); } } // Invoked when CDC interface received data from host -void tud_cdc_rx_cb(uint8_t itf) -{ - (void) itf; +void tud_cdc_rx_cb(uint8_t itf) { + (void)itf; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ -void led_blinking_task(void) -{ +void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + if (board_millis() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/webusb_serial/src/tusb_config.h b/examples/device/webusb_serial/src/tusb_config.h index fde732b9e..b86ad3752 100644 --- a/examples/device/webusb_serial/src/tusb_config.h +++ b/examples/device/webusb_serial/src/tusb_config.h @@ -102,7 +102,7 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // Vendor FIFO size of TX and RX -// If not configured vendor endpoints will not be buffered +// If zero: vendor endpoints will not be buffered #define CFG_TUD_VENDOR_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_VENDOR_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 71a395c79..ce42d7ef6 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -34,29 +34,24 @@ extern "C" { #endif -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { volatile uint8_t busy : 1; volatile uint8_t stalled : 1; volatile uint8_t claimed : 1; }tu_edpt_state_t; typedef struct { - struct { - uint8_t is_host : 1; // host or device - uint8_t is_highspeed: 1; // is highspeed - }; + uint8_t is_host; // 1: host, 0: device uint8_t ep_addr; uint16_t ep_packetsize; uint16_t ep_bufsize; - // TODO xfer_fifo can skip this buffer - uint8_t* ep_buf; + uint8_t* ep_buf; // TODO xfer_fifo can skip this buffer tu_fifo_t ff; - // mutex: read if ep rx, write if e tx + // mutex: read if rx, otherwise write OSAL_MUTEX_DEF(ff_mutexdef); }tu_edpt_stream_t; @@ -92,7 +87,6 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove bool tu_edpt_stream_deinit(tu_edpt_stream_t* s); // Open an stream for an endpoint -// hwid is either device address (host mode) or rhport (device mode) TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) { tu_fifo_clear(&s->ff); -- cgit v1.3.1 From 3ab63fbc65ce1d6333594fec23f1e2239588ea31 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Sep 2024 18:27:22 +0700 Subject: remove vendor ep_addr, use stream api instead --- .idea/cmake.xml | 12 ++++++------ src/class/vendor/vendor_device.c | 20 ++++++++------------ src/common/tusb_private.h | 1 - 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index e8b46d468..fec01a08e 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -2,8 +2,8 @@ - - + + @@ -35,7 +35,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -140,8 +140,8 @@ - - + + diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 5d33d2e60..15829991a 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -36,12 +36,8 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) - typedef struct { uint8_t itf_num; - uint8_t ep_in; - uint8_t ep_out; /*------------- From this point, data is not cleared by bus reset -------------*/ // Endpoint Transfer buffer @@ -66,20 +62,22 @@ typedef struct { CFG_TUD_MEM_SECTION static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; -#define ITF_MEM_RESET_SIZE offsetof(vendord_interface_t, ep_out) + sizeof(((vendord_interface_t *)0)->ep_out) +#define ITF_MEM_RESET_SIZE (offsetof(vendord_interface_t, itf_num) + sizeof(((vendord_interface_t *)0)->itf_num)) //-------------------------------------------------------------------- // Application API //-------------------------------------------------------------------- -bool tud_vendor_n_mounted (uint8_t itf) { - return _vendord_itf[itf].ep_in && _vendord_itf[itf].ep_out; +bool tud_vendor_n_mounted(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_VENDOR); + vendord_interface_t* p_itf = &_vendord_itf[itf]; + return p_itf->rx.stream.ep_addr || p_itf->tx.stream.ep_addr; } //--------------------------------------------------------------------+ // Read API //--------------------------------------------------------------------+ -uint32_t tud_vendor_n_available (uint8_t itf) { +uint32_t tud_vendor_n_available(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; @@ -87,7 +85,7 @@ uint32_t tud_vendor_n_available (uint8_t itf) { } bool tud_vendor_n_peek(uint8_t itf, uint8_t* u8) { - TU_VERIFY(itf < CFG_TUD_VENDOR, 0); + TU_VERIFY(itf < CFG_TUD_VENDOR); vendord_interface_t* p_itf = &_vendord_itf[itf]; return tu_edpt_stream_peek(&p_itf->rx.stream, u8); @@ -198,7 +196,7 @@ uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, ui // Find available interface vendord_interface_t* p_vendor = NULL; for(uint8_t i=0; ibEndpointAddress) == TUSB_DIR_IN) { - p_vendor->ep_in = desc_ep->bEndpointAddress; tu_edpt_stream_open(&p_vendor->tx.stream, desc_ep); tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf)); } else { - p_vendor->ep_out = desc_ep->bEndpointAddress; tu_edpt_stream_open(&p_vendor->rx.stream, desc_ep); TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_vendor->rx.stream) > 0, 0); // prepare for incoming data } diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index ce42d7ef6..2cf11ea94 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -46,7 +46,6 @@ typedef struct { uint16_t ep_packetsize; uint16_t ep_bufsize; - uint8_t* ep_buf; // TODO xfer_fifo can skip this buffer tu_fifo_t ff; -- cgit v1.3.1 From dd1822ba032e3e86efd445cda1c3fd0e8f342bbc Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Sep 2024 18:37:53 +0700 Subject: reduce ep stream footprint by using is_mps512 since it only support bulk so far --- src/common/tusb_private.h | 11 ++++++----- src/tusb.c | 13 ++++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 2cf11ea94..8a479c042 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -41,13 +41,14 @@ typedef struct TU_ATTR_PACKED { }tu_edpt_state_t; typedef struct { - uint8_t is_host; // 1: host, 0: device + struct TU_ATTR_PACKED { + uint8_t is_host : 1; // 1: host, 0: device + uint8_t is_mps512 : 1; // 1: 512, 0: 64 since stream is used for Bulk only + }; uint8_t ep_addr; - - uint16_t ep_packetsize; uint16_t ep_bufsize; - uint8_t* ep_buf; // TODO xfer_fifo can skip this buffer + uint8_t* ep_buf; // TODO xfer_fifo can skip this buffer tu_fifo_t ff; // mutex: read if rx, otherwise write @@ -90,7 +91,7 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) { tu_fifo_clear(&s->ff); s->ep_addr = desc_ep->bEndpointAddress; - s->ep_packetsize = tu_edpt_packet_size(desc_ep); + s->is_mps512 = (tu_edpt_packet_size(desc_ep) == 512) ? 1 : 0; } TU_ATTR_ALWAYS_INLINE static inline diff --git a/src/tusb.c b/src/tusb.c index 69c1f9775..bdd1fba99 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -283,7 +283,8 @@ TU_ATTR_ALWAYS_INLINE static inline bool stream_release(uint8_t hwid, tu_edpt_st //--------------------------------------------------------------------+ bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes) { // ZLP condition: no pending data, last transferred bytes is multiple of packet size - TU_VERIFY(!tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (s->ep_packetsize - 1)))); + const uint16_t mps = s->is_mps512 ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; + TU_VERIFY(!tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (mps - 1)))); TU_VERIFY(stream_claim(hwid, s)); TU_ASSERT(stream_xfer(hwid, s, 0)); return true; @@ -324,7 +325,8 @@ uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const* buf // flush if fifo has more than packet size or // in rare case: fifo depth is configured too small (which never reach packet size) - if ((tu_fifo_count(&s->ff) >= s->ep_packetsize) || (tu_fifo_depth(&s->ff) < s->ep_packetsize)) { + const uint16_t mps = s->is_mps512 ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; + if ((tu_fifo_count(&s->ff) >= mps) || (tu_fifo_depth(&s->ff) < mps)) { tu_edpt_stream_write_xfer(hwid, s); } return ret; @@ -359,22 +361,23 @@ uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s) { TU_ASSERT(stream_xfer(hwid, s, s->ep_bufsize), 0); return s->ep_bufsize; } else { + const uint16_t mps = s->is_mps512 ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; uint16_t available = tu_fifo_remaining(&s->ff); // Prepare for incoming data but only allow what we can store in the ring buffer. // TODO Actually we can still carry out the transfer, keeping count of received bytes // and slowly move it to the FIFO when read(). // This pre-check reduces endpoint claiming - TU_VERIFY(available >= s->ep_packetsize); + TU_VERIFY(available >= mps); TU_VERIFY(stream_claim(hwid, s), 0); // get available again since fifo can be changed before endpoint is claimed available = tu_fifo_remaining(&s->ff); - if (available >= s->ep_packetsize) { + if (available >= mps) { // multiple of packet size limit by ep bufsize - uint16_t count = (uint16_t) (available & ~(s->ep_packetsize - 1)); + uint16_t count = (uint16_t) (available & ~(mps - 1)); count = tu_min16(count, s->ep_bufsize); TU_ASSERT(stream_xfer(hwid, s, count), 0); return count; -- cgit v1.3.1 From 7909a6256941d001ae888530080fc572c7410b3b Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Sep 2024 18:47:58 +0700 Subject: fix warnings --- src/tusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tusb.c b/src/tusb.c index bdd1fba99..80073c259 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -318,7 +318,7 @@ uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const* buf TU_VERIFY(stream_claim(hwid, s), 0); const uint32_t xact_len = tu_min32(bufsize, s->ep_bufsize); memcpy(s->ep_buf, buffer, xact_len); - TU_ASSERT(stream_xfer(hwid, s, xact_len), 0); + TU_ASSERT(stream_xfer(hwid, s, (uint16_t) xact_len), 0); return xact_len; } else { const uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); -- cgit v1.3.1 From 9b4bb61cbd1f95d4272c4bf30e843e3807d932d5 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Sep 2024 20:39:29 +0700 Subject: ep stream init: wrap with OSAL_MUTEX_REQUIRED, only create fifo mutex if needed --- src/tusb.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tusb.c b/src/tusb.c index 80073c259..11690b203 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -216,13 +216,17 @@ uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable, void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize) { - osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutexdef); - (void) new_mutex; (void) is_tx; s->is_host = is_host; tu_fifo_config(&s->ff, ff_buf, ff_bufsize, 1, overwritable); - tu_fifo_config_mutex(&s->ff, is_tx ? new_mutex : NULL, is_tx ? NULL : new_mutex); + + #if OSAL_MUTEX_REQUIRED + if (ff_buf && ff_bufsize) { + osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutexdef); + tu_fifo_config_mutex(&s->ff, is_tx ? new_mutex : NULL, is_tx ? NULL : new_mutex); + } + #endif s->ep_buf = ep_buf; s->ep_bufsize = ep_bufsize; -- cgit v1.3.1 From 013b4488b08b818d89c05119984f804ba652f08d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 11 Sep 2024 10:20:17 +0700 Subject: [circleci] fix build with rx by get-deps before install toolchain --- .circleci/config2.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.circleci/config2.yml b/.circleci/config2.yml index 542c3d0d0..278ff0f3b 100644 --- a/.circleci/config2.yml +++ b/.circleci/config2.yml @@ -68,14 +68,6 @@ commands: steps: - checkout - - when: - condition: - not: - equal: [esp-idf, << parameters.toolchain >>] - steps: - - setup-toolchain: - toolchain: << parameters.toolchain >> - - run: name: Get Dependencies command: | @@ -101,6 +93,14 @@ commands: echo "export PICO_SDK_PATH=~/pico-sdk" >> $BASH_ENV fi + - when: + condition: + not: + equal: [esp-idf, << parameters.toolchain >>] + steps: + - setup-toolchain: + toolchain: << parameters.toolchain >> + - run: name: Build command: | -- cgit v1.3.1 From c419b1e7c57ab701c904adfe6ebf14f780862557 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 Sep 2024 19:12:26 +0700 Subject: add pico2 rp2350 (arm) board add pico2 to hil ci --- .idea/cmake.xml | 4 +++- .../boards/feather_rp2040_max3421/board.cmake | 1 + hw/bsp/rp2040/boards/raspberry_pi_pico/board.cmake | 1 + .../rp2040/boards/raspberry_pi_pico2/board.cmake | 2 ++ hw/bsp/rp2040/family.cmake | 27 +++++++++++++++------- test/hil/hil_test.py | 20 +++++++++++----- test/hil/rpi.json | 10 ++++++++ 7 files changed, 50 insertions(+), 15 deletions(-) create mode 100644 hw/bsp/rp2040/boards/raspberry_pi_pico2/board.cmake diff --git a/.idea/cmake.xml b/.idea/cmake.xml index fec01a08e..96ff19c89 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -2,7 +2,9 @@ - + + + diff --git a/hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake b/hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake index b8e5890f3..2afe0f264 100644 --- a/hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake +++ b/hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake @@ -1,3 +1,4 @@ +set(PICO_PLATFORM rp2040) set(PICO_BOARD adafruit_feather_rp2040) # Enable MAX3421E USB Host diff --git a/hw/bsp/rp2040/boards/raspberry_pi_pico/board.cmake b/hw/bsp/rp2040/boards/raspberry_pi_pico/board.cmake index f9887c09c..804cdb50a 100644 --- a/hw/bsp/rp2040/boards/raspberry_pi_pico/board.cmake +++ b/hw/bsp/rp2040/boards/raspberry_pi_pico/board.cmake @@ -1 +1,2 @@ +set(PICO_PLATFORM rp2040) set(PICO_BOARD pico) diff --git a/hw/bsp/rp2040/boards/raspberry_pi_pico2/board.cmake b/hw/bsp/rp2040/boards/raspberry_pi_pico2/board.cmake new file mode 100644 index 000000000..3482e2674 --- /dev/null +++ b/hw/bsp/rp2040/boards/raspberry_pi_pico2/board.cmake @@ -0,0 +1,2 @@ +set(PICO_PLATFORM rp2350-arm-s) +set(PICO_BOARD pico2) diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index d91821ffa..8f01eac74 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -6,21 +6,32 @@ if (NOT BOARD) set(BOARD pico_sdk) endif() -if (TOOLCHAIN STREQUAL "clang") - set(PICO_COMPILER "pico_arm_clang") -else() - set(PICO_COMPILER "pico_arm_gcc") -endif() +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +#if (TOOLCHAIN STREQUAL "clang") +# set(PICO_COMPILER "pico_arm_clang") +#else() +# set(PICO_COMPILER "pico_arm_gcc") +#endif() # add the SDK in case we are standalone tinyusb example (noop if already present) include(${CMAKE_CURRENT_LIST_DIR}/pico_sdk_import.cmake) # include basic family CMake functionality set(FAMILY_MCUS RP2040) -set(JLINK_DEVICE rp2040_m0_0) -set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"") -include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) +if (PICO_PLATFORM STREQUAL "rp2040") + set(JLINK_DEVICE rp2040_m0_0) + set(OPENOCD_TARGET rp2040) +elseif (PICO_PLATFORM STREQUAL "rp2350-arm-s" OR PICO_PLATFORM STREQUAL "rp2350") + set(JLINK_DEVICE rp2350_m33_0) + set(OPENOCD_TARGET rp2350) +elseif (PICO_PLATFORM STREQUAL "rp2350-riscv") + set(JLINK_DEVICE rp2350_riscv_0) + set(OPENOCD_TARGET rp2350-riscv) +endif() + +set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -f target/${OPENOCD_TARGET}.cfg -c \"adapter speed 5000\"") if (NOT PICO_TINYUSB_PATH) set(PICO_TINYUSB_PATH ${TOP}) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 52ec5ae1d..a569e7666 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -43,6 +43,8 @@ STATUS_OK = "\033[32mOK\033[0m" STATUS_FAILED = "\033[31mFailed\033[0m" STATUS_SKIPPED = "\033[33mSkipped\033[0m" +verbose = False + # get usb serial by id def get_serial_dev(id, vendor_str, product_str, ifnum): if vendor_str and product_str: @@ -111,7 +113,6 @@ def read_disk_file(uid, lun, fname): # Flashing firmware # ------------------------------------------------------------- def run_cmd(cmd): - #print(cmd) r = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if r.returncode != 0: title = f'COMMAND FAILED: {cmd}' @@ -123,6 +124,9 @@ def run_cmd(cmd): else: print(title) print(r.stdout.decode("utf-8")) + elif verbose: + print(cmd) + print(r.stdout.decode("utf-8")) return r @@ -260,14 +264,14 @@ def test_device_cdc_dual_ports(board): str1 = b"test_no1" ser1.write(str1) ser1.flush() - assert ser1.read(100) == str1.lower(), 'Port1 wrong data' - assert ser2.read(100) == str1.upper(), 'Port2 wrong data' + assert ser1.read(len(str1)) == str1.lower(), 'Port1 wrong data' + assert ser2.read(len(str1)) == str1.upper(), 'Port2 wrong data' str2 = b"test_no2" ser2.write(str2) ser2.flush() - assert ser1.read(100) == str2.lower(), 'Port1 wrong data' - assert ser2.read(100) == str2.upper(), 'Port2 wrong data' + assert ser1.read(len(str2)) == str2.lower(), 'Port1 wrong data' + assert ser2.read(len(str2)) == str2.upper(), 'Port2 wrong data' def test_device_cdc_msc(board): @@ -279,7 +283,7 @@ def test_device_cdc_msc(board): str = b"test_str" ser.write(str) ser.flush() - assert ser.read(100) == str, 'CDC wrong data' + assert ser.read(len(str)) == str, 'CDC wrong data' # Block test data = read_disk_file(uid,0,'README.TXT') @@ -447,13 +451,17 @@ def main(): """ Hardware test on specified boards """ + global verbose + parser = argparse.ArgumentParser() parser.add_argument('config_file', help='Configuration JSON file') parser.add_argument('-b', '--board', action='append', default=[], help='Boards to test, all if not specified') + parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output') args = parser.parse_args() config_file = args.config_file boards = args.board + verbose = args.verbose # if config file is not found, try to find it in the same directory as this script if not os.path.exists(config_file): diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 36376a873..77919f346 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -52,6 +52,16 @@ "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002470"}] } }, + { + "name": "raspberry_pi_pico2", + "uid": "560AE75E1C7152C9", + "flasher": "openocd", + "flasher_sn": "E6633861A3978538", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2350.cfg -c \"adapter speed 5000\"", + "tests": { + "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "533D004242"}] + } + }, { "name": "stm32f072disco", "uid": "3A001A001357364230353532", -- cgit v1.3.1 From 115b1bb71eec878a9e4bd06a1751f64ecfa2dcce Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 Sep 2024 23:23:37 +0700 Subject: prepare for 0.17.0 release --- README.rst | 6 +- docs/info/changelog.rst | 144 ++++++++++++++++++---- docs/reference/dependencies.rst | 12 +- docs/reference/supported.rst | 262 +++++++++++++++++++--------------------- library.json | 2 +- repository.yml | 3 +- tools/make_release.py | 2 +- 7 files changed, 259 insertions(+), 172 deletions(-) diff --git a/README.rst b/README.rst index 2ffe3823a..502115c25 100644 --- a/README.rst +++ b/README.rst @@ -77,7 +77,7 @@ Host Stack - Human Interface Device (HID): Keyboard, Mouse, Generic - Mass Storage Class (MSC) - Communication Device Class: CDC-ACM -- Vendor serial over USB: FTDI, CP210x +- Vendor serial over USB: FTDI, CP210x, CH34x - Hub with multiple-level support Similar to the Device Stack, if you have a special requirement, `usbh_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. @@ -111,7 +111,7 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l +--------------+------------------------------------------------------------+ | Analog | max32: 650, 666, 690. max78002 | | | | -| | max3421e (host) | +| | max3421e (spi host) | +--------------+------------------------------------------------------------+ | Brigetek | FT90x | +--------------+------------------------------------------------------------+ @@ -143,7 +143,7 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l | | | | | MCX: A15, N9 | +--------------+------------------------------------------------------------+ -| Raspberry Pi | RP2040 | +| Raspberry Pi | RP2040, RP2350 | +--------------+-----+------------------------------------------------------+ | Renesas | RA: 4M1, 4M3, 6M1, 6M5 | | | | diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index f7ccb39b9..d11e1134a 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -2,71 +2,165 @@ Changelog ********* -0.17.0 (WIP) -============ +0.17.0 +====== General ------- -- Improved continuous integration: build both cmake and make. Make use of circleci to build arm-clang - +- Improved CI: build both cmake and make. Make use of CircleCI for part of build process to speed up CI +- Add CodeQL Workflow for Code Security Analysis +- Add Clang compiler support +- Add default implementation for weak callbacks functions for better Keil compatibility +- Upgrade hardware-in-the-loop (HIL) testing with more boards and examples: including dual stack example Controller Driver (DCD & HCD) ----------------------------- +- Chipidea + + - Support MCXA + +- DWC2 + + - Fix tickless issue with stm32f7: disable ULPI clock during sleep when using internal phy + - Fix SOF interrupt handling + - Fix fifo level half/empty issue + - Add DWC2 Test Mode support. + - for esp32 force disconnect/connect using USB_WRAP otg pad override + +- FSDEV + + - Rewrite and Generalize driver to support non-stm32 mcu such as wch + - Simplify PMA, HW FIFO access and bit manipulation for different access scheme 1x16, 2x16 and 32 bit + - Add support for ch32 usbd e.g ch32v203 + - Add support for STM32G4 and STM32U5 microcontrollers. + - Fix h5 (32-bit) errata 2.15.1: Buffer description table update completes after CTR interrupt triggers + - ISO EP buffer allocation improvements, implement dcd_edpt_close_all() + + - Fix ch32v203 race condition and stability issue with + + - fix ch32v203 seems to unconditionally accept ZLP on EP0 OUT. + - fix v203 race condition between rx bufsize and RX_STAT which cause PMAOVR, occurs with WRITE10 + - correctly handle setup prepare at dcd_edpt0_status_complete(), which fixes the race condition with windows where we could miss setup packet (setup bit set, but count = 0) + +- MAX3421E + + - Add support for rp2040, esp32 (c3, c6, h2, etc..) + - Add hcd_deinit() for max3421 + - Retry NAK handling next frame to reduce CPU and SPI bus usage + - add cpuctl and pinctl to tuh_configure() option for max3421 + - Implement hcd abort transfer for Max3421 + - Properly Handle NAK Response in MAX3421E driver: correctly switch and skip writing to 2 FIFOs when NAK received. Otherwise, the driver may hang in certain conditions. + +- MSP430: support non-bus-powered + +- MUSB + + - Add support for Analoog devices: max32650, max32666, max32690, max3278002 + +- nRF + + - Fix dcd_edpt_open for iso endpoint + - Handle ISOOUT CRC errors + - Add compile support with old nordic sdk + - Fix a few race conditions + +- OHCI + + - Allow more than 16 devices + +- RP2040 + + - Correctly abort control transfer when new setup arrived. Due to RP2040-E2 only able to fix B2 or later + - Implement hcd abort transfer for rp2040 + - Add support for rp2350 + +- RUSB2 + + - Support ra2a1 pipe number scheme + - WCH CH32 - Added support for USB OTG/FS and FSDev Driver. Update CH32V307 to allow manual select FS or HS driver. - Fixed various bugs in CH32v307 usbhs driver: endpoint handling and data transfer management. -- Fixed race conditions and other bugs in dcd_nrf5x and other drivers. -- Implemented hcd abort transfer for Max3421 and rp2040 -- Added DWC2 Test Mode support. -- stm32 fsdev: ISO EP buffer allocation improvements, implement dcd_edpt_close_all() -- Added support for STM32G4 and STM32U5 microcontrollers. - Device Stack ------------ -- Added tud_deinit() to deinitialize TinyUSB device stack. -- Added support for generic SOF callback. +- Add tud_deinit() and class driver deinit() to deinitialize TinyUSB device stack. +- Add support for generic SOF callback. +- Add set address recovery time 2ms per USB spec. - Audio - Add audio_test_freertos & audio_4_channel_mic_freertos - Improved support for Audio Class 2.0 (UAC2) with various bug fixes. + - Add feedback by fifo counting. + +- Bluetooth HCI + + - Issue ZLP on ACL IN ep when transfer is multiple of endpoint max packet size + +- CDC + + - Add tud_cdc_configure_fifo() to make RX/TX buffer persistent (not clear when disconnected) + - Add missing capability bit for CDC ACM serial break support + - Enhanced CDC class with better handling of large data transmissions. + - Add missing capability bit for CDC ACM serial break support - HID - Added missing key codes for keypad - Added HID Lighting and Illumination functionality + - Fixed issues in the HID class for more reliable device enumeration. + - Support HID Mouse with absolute positioning + - Use separate buffer for control SET_REPORT, fix conflict with interrupt endpoint out -- Vendor: Added empty transfers for tud_vendor_n_write() - MSC: Added support for SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL -- CDC - - - Add option to make CDC TX buffer persistent - - Add missing capability bit for CDC ACM serial break support - - Net - - Rewrite of NCM device driver + - Rewrite of NCM device driver to improve throughput - removed obsolete tud_network_link_state_cb() -- Enhanced CDC class with better handling of large data transmissions. -- Fixed issues in the HID class for more reliable device enumeration. -- Video Added support for USB Video Class (UVC) with MJPEG. - USBTMC Added notification support +- Vendor + + - Migrate to new endpoint stream API, support non-buffered TX/RX + - Add ZLP for write() when needed + +- Video + + - Enhance UVC descriptors and example + - Video Added support for USB Video Class (UVC) with MJPEG. + - Fix multiple interfaces, add an example of 2ch video capture. + - Fix race for tud_video_n_streaming check + Host Stack ---------- -- Added tuh_deinit() to deinitialize TinyUSB host stack. +- Added tuh_deinit() to de-initialize TinyUSB host stack. - Added support for new USB mass storage class APIs. -- Enhanced stability of CDC-ACM devices during enumeration. - Improved error handling and retry mechanisms for unstable devices. -- Added support for multiple interfaces in UVC. + +- CDC Serial + + - Add support for ch34x + - Allow to overwrite CFG_TUH_CDC_FTDI/CP210X/CH32X_VID_PID_LIST + - Enhanced stability of CDC-ACM devices during enumeration. + +- HID + + - Add tuh_hid_receive_abort() + - Add tuh_hid_get_report() + +- Hub + + - Prevent status request to invalid ep_num + - Fix double status xfer + - unroll hub removal 0.16.0 ====== diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index fd895519e..65ee31f22 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -8,6 +8,7 @@ MCU low-level peripheral driver and external libraries for building TinyUSB exam Local Path Repo Commit Required by ======================================== ============================================================== ======================================== ========================================================================================================================================================================================================================================================================================================================== hw/mcu/allwinner https://github.com/hathach/allwinner_driver.git 8e5e89e8e132c0fd90e72d5422e5d3d68232b756 fc100s +hw/mcu/analog/max32 https://github.com/analogdevicesinc/msdk.git b20b398d3e5e2007594e54a74ba3d2a2e50ddd75 max32650 max32666 max32690 max78002 hw/mcu/bridgetek/ft9xx/ft90x-sdk https://github.com/BRTSG-FOSS/ft90x-sdk.git 91060164afe239fcb394122e8bf9eb24d3194eb1 brtmm90x hw/mcu/broadcom https://github.com/adafruit/broadcom-peripherals.git 08370086080759ed54ac1136d62d2ad24c6fa267 broadcom_32bit broadcom_64bit hw/mcu/gd/nuclei-sdk https://github.com/Nuclei-Software/nuclei-sdk.git 7eb7bfa9ea4fbeacfafe1d5f77d5a0e6ed3922e7 gd32vf103 @@ -16,9 +17,9 @@ hw/mcu/microchip https://github.com/hathach/microchip_d hw/mcu/mindmotion/mm32sdk https://github.com/hathach/mm32sdk.git b93e856211060ae825216c6a1d6aa347ec758843 mm32 hw/mcu/nordic/nrfx https://github.com/NordicSemiconductor/nrfx.git 7c47cc0a56ce44658e6da2458e86cd8783ccc4a2 nrf hw/mcu/nuvoton https://github.com/majbthrd/nuc_driver.git 2204191ec76283371419fbcec207da02e1bc22fa nuc -hw/mcu/nxp/lpcopen https://github.com/hathach/nxp_lpcopen.git 04bfe7a5f6ee74a89a28ad618d3367dcfcfb7d83 lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 +hw/mcu/nxp/lpcopen https://github.com/hathach/nxp_lpcopen.git b41cf930e65c734d8ec6de04f1d57d46787c76ae lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 hw/mcu/nxp/mcux-sdk https://github.com/hathach/mcux-sdk.git 144f1eb7ea8c06512e12f12b27383601c0272410 kinetis_k kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx imxrt -hw/mcu/raspberry_pi/Pico-PIO-USB https://github.com/sekigon-gonnoc/Pico-PIO-USB.git 0f747aaa0c16f750bdfa2ba37ec25d6c8e1bc117 rp2040 +hw/mcu/raspberry_pi/Pico-PIO-USB https://github.com/sekigon-gonnoc/Pico-PIO-USB.git fe9133fc513b82cc3dc62c67cb51f2339cf29ef7 rp2040 hw/mcu/renesas/fsp https://github.com/renesas/fsp.git d52e5a6a59b7c638da860c2bb309b6e78e752ff8 ra hw/mcu/renesas/rx https://github.com/kkitayam/rx_device.git 706b4e0cf485605c32351e2f90f5698267996023 rx hw/mcu/silabs/cmsis-dfp-efm32gg12b https://github.com/cmsis-packs/cmsis-dfp-efm32gg12b.git f1c31b7887669cb230b3ea63f9b56769078960bc efm32 @@ -57,11 +58,12 @@ hw/mcu/st/stm32u5xx_hal_driver https://github.com/STMicroelectronics/ hw/mcu/st/stm32wbxx_hal_driver https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git 2c5f06638be516c1b772f768456ba637f077bac8 stm32wb hw/mcu/ti https://github.com/hathach/ti_driver.git 143ed6cc20a7615d042b03b21e070197d473e6e5 msp430 msp432e4 tm4c hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.git 77c4095087e5ed2c548ec9058e655d0b8757663b ch32f20x -hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git de6d68c654340d7f27b00cebbfc9aa2740a1abc2 ch32v20x -hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 17761f5cf9dbbf2dcf665b7c04934188add20082 ch32v307 +hw/mcu/wch/ch32v103 https://github.com/openwch/ch32v103.git 7578cae0b21f86dd053a1f781b2fc6ab99d0ec17 ch32v10x +hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git c4c38f507e258a4e69b059ccc2dc27dde33cea1b ch32v20x +hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 184f21b852cb95eed58e86e901837bc9fff68775 ch32v307 lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 20285262657d1b482d132d20d755c8c330d55c1f imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf ra saml2xlpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wbsam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samgtm4c lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git cc0e0707c0c748713485b870bb980852b210877f all lib/lwip https://github.com/lwip-tcpip/lwip.git 159e31b689577dbf69cf0683bbaffbd71fa5ee10 all lib/sct_neopixel https://github.com/gsteiert/sct_neopixel.git e73e04ca63495672d955f9268e003cffe168fcd8 lpc55 -tools/uf2 https://github.com/microsoft/uf2.git 19615407727073e36d81bf239c52108ba92e7660 all +tools/uf2 https://github.com/microsoft/uf2.git c594542b2faa01cc33a2b97c9fbebc38549df80a all ======================================== ============================================================== ======================================== ========================================================================================================================================================================================================================================================================================================================== diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 2bfa1b8d0..b871490dc 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -5,142 +5,132 @@ Supported Devices Supported MCUs ============== -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| Manufacturer | Family | Device | Host | Highspeed | Driver | Note | -+==============+=============================+========+======+===========+===================+===================+ -| Allwinner | F1C100s/F1C200s | ✔ | | ✔ | sunxi | musb variant | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| Analog | MAX3421E | | ✔ | ✖ | max3421 | via SPI | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | MAX32 650, 666, 690, | ✔ | | ✔ | musb | 1-dir ep | -| | MAX78002 | | | | | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| Brigetek | FT90x | ✔ | | ✔ | ft9xx | 1-dir ep | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| Broadcom | BCM2711, BCM2837 | ✔ | | ✔ | dwc2 | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| Espressif | ESP32 S2, S3 | ✔ | | ✖ | dwc2 or esp32sx | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| Infineon | XMC4500 | ✔ | | ✖ | dwc2 | | -+--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+ -| MicroChip | SAM | D11, D21, L21, L22 | ✔ | | ✖ | samd | | -| | +-----------------------+--------+------+-----------+-------------------+-------------------+ -| | | D51, E5x | ✔ | | ✖ | samd | | -| | +-----------------------+--------+------+-----------+-------------------+-------------------+ -| | | G55 | ✔ | | ✖ | samg | 1-dir ep | -| | +-----------------------+--------+------+-----------+-------------------+-------------------+ -| | | E70,S70,V70,V71 | ✔ | | ✔ | samx7x | 1-dir ep | -| +-----+-----------------------+--------+------+-----------+-------------------+-------------------+ -| | PIC | 24 | ✔ | | | pic | ci_fs variant | -| | +-----------------------+--------+------+-----------+-------------------+-------------------+ -| | | 32 mm, mk, mx | ✔ | | | pic | ci_fs variant | -| | +-----------------------+--------+------+-----------+-------------------+-------------------+ -| | | dsPIC33 | ✔ | | | pic | ci_fs variant | -| | +-----------------------+--------+------+-----------+-------------------+-------------------+ -| | | 32mz | ✔ | | | pic32mz | musb variant | -+--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+ -| Mind Montion | mm32 | ✔ | | ✖ | mm32f327x_otg | ci_fs variant | -+--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+ -| NordicSemi | nRF 52833, 52840, 5340 | ✔ | ✖ | ✖ | nrf5x | only ep8 is ISO | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| Nuvoton | NUC120 | ✔ | ✖ | ✖ | nuc120 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | NUC121/NUC125 | ✔ | ✖ | ✖ | nuc121 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | NUC126 | ✔ | ✖ | ✖ | nuc121 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | NUC505 | ✔ | | ✔ | nuc505 | | -+--------------+---------+-------------------+--------+------+-----------+-------------------+-------------------+ -| NXP | iMXRT | RT 10xx, 11xx | ✔ | ✔ | ✔ | ci_hs | | -| +---------+-------------------+--------+------+-----------+-------------------+-------------------+ -| | Kinetis | KL | ✔ | âš  | ✖ | ci_fs, khci | | -| | +-------------------+--------+------+-----------+-------------------+-------------------+ -| | | K32L2 | ✔ | | ✖ | khci | ci_fs variant | -| +---------+-------------------+--------+------+-----------+-------------------+-------------------+ -| | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | | -| | +-------------------+--------+------+-----------+-------------------+-------------------+ -| | | 17, 40 | ✔ | âš  | ✖ | lpc17_40 | | -| | +-------------------+--------+------+-----------+-------------------+-------------------+ -| | | 18, 43 | ✔ | ✔ | ✔ | ci_hs | | -| | +-------------------+--------+------+-----------+-------------------+-------------------+ -| | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | | -| | +-------------------+--------+------+-----------+-------------------+-------------------+ -| | | 54, 55 | ✔ | | ✔ | lpc_ip3511 | | -| +---------+-------------------+--------+------+-----------+-------------------+-------------------+ -| | MCX | N9 | ✔ | | ✔ | ci_fs, ci_hs | | -+--------------+---------+-------------------+--------+------+-----------+-------------------+-------------------+ -| Raspberry Pi | RP2040, RP2350 | ✔ | ✔ | ✖ | rp2040, pio_usb | | -+--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+ -| Renesas | RX | 63N, 65N, 72N | ✔ | ✔ | ✖ | rusb2 | | -| +-----+-----------------------+--------+------+-----------+-------------------+-------------------+ -| | RA | 4M1, 4M3, 6M1 | ✔ | ✔ | ✖ | rusb2 | | -| | +-----------------------+--------+------+-----------+-------------------+-------------------+ -| | | 6M5 | ✔ | ✔ | ✔ | rusb2 | | -+--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+ -| Silabs | EFM32GG12 | ✔ | | ✖ | dwc2 | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| Sony | CXD56 | ✔ | ✖ | ✔ | cxd56 | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| ST STM32 | F0 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +----+------------------------+--------+------+-----------+-------------------+-------------------+ -| | F1 | 102, 103 | ✔ | ✖ | ✖ | stm32_fsdev | | -| | +------------------------+--------+------+-----------+-------------------+-------------------+ -| | | 105, 107 | ✔ | | ✖ | dwc2 | | -| +----+------------------------+--------+------+-----------+-------------------+-------------------+ -| | F2 | ✔ | | ✔ | dwc2 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | F3 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | F4 | ✔ | | ✔ | dwc2 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | F7 | ✔ | | ✔ | dwc2 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | G0 | ✔ | | ✖ | stm32_fsdev | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | H5 | ✔ | | ✖ | stm32_fsdev | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | H7 | ✔ | | ✔ | dwc2 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | L0 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | L1 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +----+------------------------+--------+------+-----------+-------------------+-------------------+ -| | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | | -| | +------------------------+--------+------+-----------+-------------------+-------------------+ -| | | 4x5, 4x6 | ✔ | | ✖ | dwc2 | | -| +----+------------------------+--------+------+-----------+-------------------+-------------------+ -| | L4+ | ✔ | | ✖ | dwc2 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | L5 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +----+------------------------+--------+------+-----------+-------------------+-------------------+ -| | U5 | 535, 545 | ✔ | | ✖ | stm32_fsdev | | -| | +------------------------+--------+------+-----------+-------------------+-------------------+ -| | | 575, 585 | ✔ | | ✖ | dwc2 | | -| | +------------------------+--------+------+-----------+-------------------+-------------------+ -| | | 59x,5Ax,5Fx,5Gx | ✔ | | ✔ | dwc2 | | -| +----+------------------------+--------+------+-----------+-------------------+-------------------+ -| | WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | MSP432E4 | ✔ | | ✖ | musb | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | TM4C123 | ✔ | | ✖ | musb | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| WCH | CH32F20x | ✔ | | ✔ | ch32f205 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | CH32V20x | ✔ | | ✖ | ch32v20x | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | CH32V307 | ✔ | | ✔ | ch32v307 | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| Manufacturer | Family | Device | Host | Highspeed | Driver | Note | ++==============+=============================+========+======+===========+========================+===================+ +| Allwinner | F1C100s/F1C200s | ✔ | | ✔ | sunxi | musb variant | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| Analog | MAX3421E | | ✔ | ✖ | max3421 | via SPI | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | MAX32 650, 666, 690, | ✔ | | ✔ | musb | 1-dir ep | +| | MAX78002 | | | | | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| Brigetek | FT90x | ✔ | | ✔ | ft9xx | 1-dir ep | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| Broadcom | BCM2711, BCM2837 | ✔ | | ✔ | dwc2 | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| Espressif | ESP32 S2, S3 | ✔ | | ✖ | dwc2 or esp32sx | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| Infineon | XMC4500 | ✔ | | ✖ | dwc2 | | ++--------------+-----+-----------------------+--------+------+-----------+------------------------+-------------------+ +| MicroChip | SAM | D11, D21, L21, L22 | ✔ | | ✖ | samd | | +| | +-----------------------+--------+------+-----------+------------------------+-------------------+ +| | | D51, E5x | ✔ | | ✖ | samd | | +| | +-----------------------+--------+------+-----------+------------------------+-------------------+ +| | | G55 | ✔ | | ✖ | samg | 1-dir ep | +| | +-----------------------+--------+------+-----------+------------------------+-------------------+ +| | | E70,S70,V70,V71 | ✔ | | ✔ | samx7x | 1-dir ep | +| +-----+-----------------------+--------+------+-----------+------------------------+-------------------+ +| | PIC | 24 | ✔ | | | pic | ci_fs variant | +| | +-----------------------+--------+------+-----------+------------------------+-------------------+ +| | | 32 mm, mk, mx | ✔ | | | pic | ci_fs variant | +| | +-----------------------+--------+------+-----------+------------------------+-------------------+ +| | | dsPIC33 | ✔ | | | pic | ci_fs variant | +| | +-----------------------+--------+------+-----------+------------------------+-------------------+ +| | | 32mz | ✔ | | | pic32mz | musb variant | ++--------------+-----+-----------------------+--------+------+-----------+------------------------+-------------------+ +| Mind Montion | mm32 | ✔ | | ✖ | mm32f327x_otg | ci_fs variant | ++--------------+-----+-----------------------+--------+------+-----------+------------------------+-------------------+ +| NordicSemi | nRF 52833, 52840, 5340 | ✔ | ✖ | ✖ | nrf5x | only ep8 is ISO | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| Nuvoton | NUC120 | ✔ | ✖ | ✖ | nuc120 | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | NUC121/NUC125 | ✔ | ✖ | ✖ | nuc121 | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | NUC126 | ✔ | ✖ | ✖ | nuc121 | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | NUC505 | ✔ | | ✔ | nuc505 | | ++--------------+---------+-------------------+--------+------+-----------+------------------------+-------------------+ +| NXP | iMXRT | RT 10xx, 11xx | ✔ | ✔ | ✔ | ci_hs | | +| +---------+-------------------+--------+------+-----------+------------------------+-------------------+ +| | Kinetis | KL | ✔ | âš  | ✖ | ci_fs, khci | | +| | +-------------------+--------+------+-----------+------------------------+-------------------+ +| | | K32L2 | ✔ | | ✖ | khci | ci_fs variant | +| +---------+-------------------+--------+------+-----------+------------------------+-------------------+ +| | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | | +| | +-------------------+--------+------+-----------+------------------------+-------------------+ +| | | 17, 40 | ✔ | âš  | ✖ | lpc17_40 | | +| | +-------------------+--------+------+-----------+------------------------+-------------------+ +| | | 18, 43 | ✔ | ✔ | ✔ | ci_hs | | +| | +-------------------+--------+------+-----------+------------------------+-------------------+ +| | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | | +| | +-------------------+--------+------+-----------+------------------------+-------------------+ +| | | 54, 55 | ✔ | | ✔ | lpc_ip3511 | | +| +---------+-------------------+--------+------+-----------+------------------------+-------------------+ +| | MCX | N9, A15 | ✔ | | ✔ | ci_fs, ci_hs | | ++--------------+---------+-------------------+--------+------+-----------+------------------------+-------------------+ +| Raspberry Pi | RP2040, RP2350 | ✔ | ✔ | ✖ | rp2040, pio_usb | | ++--------------+-----+-----------------------+--------+------+-----------+------------------------+-------------------+ +| Renesas | RX | 63N, 65N, 72N | ✔ | ✔ | ✖ | rusb2 | | +| +-----+-----------------------+--------+------+-----------+------------------------+-------------------+ +| | RA | 4M1, 4M3, 6M1 | ✔ | ✔ | ✖ | rusb2 | | +| | +-----------------------+--------+------+-----------+------------------------+-------------------+ +| | | 6M5 | ✔ | ✔ | ✔ | rusb2 | | ++--------------+-----+-----------------------+--------+------+-----------+------------------------+-------------------+ +| Silabs | EFM32GG12 | ✔ | | ✖ | dwc2 | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| Sony | CXD56 | ✔ | ✖ | ✔ | cxd56 | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| ST STM32 | F0 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +----+------------------------+--------+------+-----------+------------------------+-------------------+ +| | F1 | 102, 103 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | +------------------------+--------+------+-----------+------------------------+-------------------+ +| | | 105, 107 | ✔ | | ✖ | dwc2 | | +| +----+------------------------+--------+------+-----------+------------------------+-------------------+ +| | F2, F4, F7, H7 | ✔ | | ✔ | dwc2 | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | F3 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | G0, H5 | ✔ | | ✖ | stm32_fsdev | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | L0, L1 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | +------------------------+--------+------+-----------+------------------------+-------------------+ +| | | 4x5, 4x6 | ✔ | | ✖ | dwc2 | | +| +----+------------------------+--------+------+-----------+------------------------+-------------------+ +| | L4+ | ✔ | | ✖ | dwc2 | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | L5 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +----+------------------------+--------+------+-----------+------------------------+-------------------+ +| | U5 | 535, 545 | ✔ | | ✖ | stm32_fsdev | | +| | +------------------------+--------+------+-----------+------------------------+-------------------+ +| | | 575, 585 | ✔ | | ✖ | dwc2 | | +| | +------------------------+--------+------+-----------+------------------------+-------------------+ +| | | 59x,5Ax,5Fx,5Gx | ✔ | | ✔ | dwc2 | | +| +----+------------------------+--------+------+-----------+------------------------+-------------------+ +| | WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | MSP432E4 | ✔ | | ✖ | musb | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | TM4C123 | ✔ | | ✖ | musb | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| WCH | CH32F20x | ✔ | | ✔ | ch32_usbhs | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | CH32V20x | ✔ | | ✖ | stm32_fsdev/ch32_usbfs | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | CH32V307 | ✔ | | ✔ | ch32_usbfs/hs | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ Table Legend diff --git a/library.json b/library.json index 3cdd5990f..c945d4b52 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "TinyUSB", - "version": "0.16.0", + "version": "0.17.0", "description": "TinyUSB is an open-source cross-platform USB Host/Device stack for embedded system, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events are deferred then handled in the non-ISR task function.", "keywords": "usb, host, device", "repository": diff --git a/repository.yml b/repository.yml index 28666d2d4..df7895e84 100644 --- a/repository.yml +++ b/repository.yml @@ -14,5 +14,6 @@ repo.versions: "0.14.0": "0.14.0" "0.15.0": "0.15.0" "0.16.0": "0.16.0" - "0-latest": "0.16.0" + "0.17.0": "0.17.0" + "0-latest": "0.17.0" "0-dev": "0.0.0" diff --git a/tools/make_release.py b/tools/make_release.py index 126e07292..3e653c12d 100644 --- a/tools/make_release.py +++ b/tools/make_release.py @@ -1,7 +1,7 @@ import re import gen_doc -version = '0.16.0' +version = '0.17.0' print('version {}'.format(version)) ver_id = version.split('.') -- cgit v1.3.1 From 2c27f29f713d80da53f26a8b06173ac4e1f8de05 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 14 Sep 2024 20:23:31 +0200 Subject: Add STM32 B_5585I-IOT2A board --- hw/bsp/stm32u5/boards/b_u585i_iot2a/board.cmake | 8 ++ hw/bsp/stm32u5/boards/b_u585i_iot2a/board.h | 112 ++++++++++++++++++++++++ hw/bsp/stm32u5/boards/b_u585i_iot2a/board.mk | 11 +++ 3 files changed, 131 insertions(+) create mode 100644 hw/bsp/stm32u5/boards/b_u585i_iot2a/board.cmake create mode 100644 hw/bsp/stm32u5/boards/b_u585i_iot2a/board.h create mode 100644 hw/bsp/stm32u5/boards/b_u585i_iot2a/board.mk diff --git a/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.cmake b/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.cmake new file mode 100644 index 000000000..1cb92d710 --- /dev/null +++ b/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.cmake @@ -0,0 +1,8 @@ +set(MCU_VARIANT stm32u585xx) +set(JLINK_DEVICE stm32u585zi) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32U585xx + ) +endfunction() diff --git a/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.h b/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.h new file mode 100644 index 000000000..2f1c451db --- /dev/null +++ b/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.h @@ -0,0 +1,112 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +// LED GREEN +#define LED_PORT GPIOH +#define LED_PIN GPIO_PIN_7 +#define LED_STATE_ON 0 + +// BUTTON +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +// UART Enable for STLink VCOM +#define UART_DEV USART1 +#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE +#define UART_GPIO_PORT GPIOA +#define UART_GPIO_AF GPIO_AF7_USART1 +#define UART_TX_PIN GPIO_PIN_9 +#define UART_RX_PIN GPIO_PIN_10 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ + +static void SystemClock_Config(void) { + RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; + RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; + RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 }; + + /* Enable Power Clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /** Configure the main internal regulator output voltage + */ + HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSI; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV1; + RCC_OscInitStruct.PLL.PLLM = 1; + RCC_OscInitStruct.PLL.PLLN = 10; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLR = 1; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLLVCIRANGE_1; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_CLK48; + PeriphClkInit.IclkClockSelection = RCC_CLK48CLKSOURCE_HSI48; + + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = + RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_PCLK3; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1; + + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); +} + +static void SystemPower_Config(void) { +} + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.mk b/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.mk new file mode 100644 index 000000000..ae63afef3 --- /dev/null +++ b/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.mk @@ -0,0 +1,11 @@ +CFLAGS += \ + -DSTM32U585xx \ + +# All source paths should be relative to the top level. +LD_FILE = ${FAMILY_PATH}/linker/STM32U575xx_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u575xx.s + +MCU_VARIANT = stm32u585xx +# For flash-jlink target +JLINK_DEVICE = stm32u585zi -- cgit v1.3.1 From 616532892d913b7224806ed1e881b72ed66bb3e1 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Tue, 17 Sep 2024 12:17:12 -0700 Subject: make all python files executable and standardize interpreter --- .github/workflows/ci_set_matrix.py | 1 + docs/conf.py | 1 + examples/device/audio_4_channel_mic/src/plot_audio_samples.py | 1 + examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py | 1 + examples/device/audio_test/src/plot_audio_samples.py | 1 + examples/device/audio_test_freertos/src/plot_audio_samples.py | 1 + examples/device/audio_test_multi_rate/src/plot_audio_samples.py | 1 + examples/device/hid_generic_inout/hid_test.py | 1 + examples/device/uac2_speaker_fb/src/audio_debug.py | 1 + examples/device/usbtmc/visaQuery.py | 0 hw/bsp/fomu/dfu.py | 2 +- hw/mcu/sony/cxd56/tools/flash_writer.py | 2 +- hw/mcu/sony/cxd56/tools/xmodem.py | 1 + src/portable/synopsys/dwc2/dwc2_info.py | 1 + test/hil/hil_test.py | 1 + test/unit-test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py | 2 +- test/unit-test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py | 1 + tools/build.py | 1 + tools/build_utils.py | 1 + tools/gen_doc.py | 1 + tools/get_deps.py | 1 + tools/iar_gen.py | 2 +- tools/make_release.py | 1 + tools/mksunxi.py | 0 tools/pcapng_to_corpus.py | 2 +- 25 files changed, 23 insertions(+), 5 deletions(-) mode change 100644 => 100755 .github/workflows/ci_set_matrix.py mode change 100644 => 100755 docs/conf.py mode change 100644 => 100755 examples/device/audio_4_channel_mic/src/plot_audio_samples.py mode change 100644 => 100755 examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py mode change 100644 => 100755 examples/device/audio_test/src/plot_audio_samples.py mode change 100644 => 100755 examples/device/audio_test_freertos/src/plot_audio_samples.py mode change 100644 => 100755 examples/device/audio_test_multi_rate/src/plot_audio_samples.py mode change 100644 => 100755 examples/device/hid_generic_inout/hid_test.py mode change 100644 => 100755 examples/device/uac2_speaker_fb/src/audio_debug.py mode change 100644 => 100755 examples/device/usbtmc/visaQuery.py mode change 100644 => 100755 hw/bsp/fomu/dfu.py mode change 100644 => 100755 hw/mcu/sony/cxd56/tools/xmodem.py mode change 100644 => 100755 src/portable/synopsys/dwc2/dwc2_info.py mode change 100644 => 100755 test/hil/hil_test.py mode change 100644 => 100755 test/unit-test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py mode change 100644 => 100755 test/unit-test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py mode change 100644 => 100755 tools/build.py mode change 100644 => 100755 tools/build_utils.py mode change 100644 => 100755 tools/gen_doc.py mode change 100644 => 100755 tools/get_deps.py mode change 100644 => 100755 tools/iar_gen.py mode change 100644 => 100755 tools/make_release.py mode change 100644 => 100755 tools/mksunxi.py diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py old mode 100644 new mode 100755 index 4da26bfea..fde6e81d6 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import json # toolchain, url diff --git a/docs/conf.py b/docs/conf.py old mode 100644 new mode 100755 index 878b29645..af44b7339 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full diff --git a/examples/device/audio_4_channel_mic/src/plot_audio_samples.py b/examples/device/audio_4_channel_mic/src/plot_audio_samples.py old mode 100644 new mode 100755 index d17a908b6..4d61e7f5e --- a/examples/device/audio_4_channel_mic/src/plot_audio_samples.py +++ b/examples/device/audio_4_channel_mic/src/plot_audio_samples.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import sounddevice as sd import matplotlib.pyplot as plt import numpy as np diff --git a/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py b/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py old mode 100644 new mode 100755 index 8312b4e28..4d5ca28d6 --- a/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py +++ b/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import sounddevice as sd import matplotlib.pyplot as plt import numpy as np diff --git a/examples/device/audio_test/src/plot_audio_samples.py b/examples/device/audio_test/src/plot_audio_samples.py old mode 100644 new mode 100755 index 1504684a6..ea6aa661e --- a/examples/device/audio_test/src/plot_audio_samples.py +++ b/examples/device/audio_test/src/plot_audio_samples.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import sounddevice as sd import matplotlib.pyplot as plt import numpy as np diff --git a/examples/device/audio_test_freertos/src/plot_audio_samples.py b/examples/device/audio_test_freertos/src/plot_audio_samples.py old mode 100644 new mode 100755 index 304b2d5de..46738eb3f --- a/examples/device/audio_test_freertos/src/plot_audio_samples.py +++ b/examples/device/audio_test_freertos/src/plot_audio_samples.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import sounddevice as sd import matplotlib.pyplot as plt import numpy as np diff --git a/examples/device/audio_test_multi_rate/src/plot_audio_samples.py b/examples/device/audio_test_multi_rate/src/plot_audio_samples.py old mode 100644 new mode 100755 index c92e49957..1f33a003e --- a/examples/device/audio_test_multi_rate/src/plot_audio_samples.py +++ b/examples/device/audio_test_multi_rate/src/plot_audio_samples.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import sounddevice as sd import matplotlib.pyplot as plt import numpy as np diff --git a/examples/device/hid_generic_inout/hid_test.py b/examples/device/hid_generic_inout/hid_test.py old mode 100644 new mode 100755 index 5bdba9db0..3aaca9d2c --- a/examples/device/hid_generic_inout/hid_test.py +++ b/examples/device/hid_generic_inout/hid_test.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # Install python3 HID package https://pypi.org/project/hid/ import hid diff --git a/examples/device/uac2_speaker_fb/src/audio_debug.py b/examples/device/uac2_speaker_fb/src/audio_debug.py old mode 100644 new mode 100755 index 336c46c01..05b49baf6 --- a/examples/device/uac2_speaker_fb/src/audio_debug.py +++ b/examples/device/uac2_speaker_fb/src/audio_debug.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # Install python3 HID package https://pypi.org/project/hid/ # Install python3 matplotlib package https://pypi.org/project/matplotlib/ diff --git a/examples/device/usbtmc/visaQuery.py b/examples/device/usbtmc/visaQuery.py old mode 100644 new mode 100755 diff --git a/hw/bsp/fomu/dfu.py b/hw/bsp/fomu/dfu.py old mode 100644 new mode 100755 index 32479350c..8383852e3 --- a/hw/bsp/fomu/dfu.py +++ b/hw/bsp/fomu/dfu.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # Written by Antonio Galea - 2010/11/18 # Updated for DFU 1.1 by Sean Cross - 2020/03/31 diff --git a/hw/mcu/sony/cxd56/tools/flash_writer.py b/hw/mcu/sony/cxd56/tools/flash_writer.py index bf630547a..387e679da 100755 --- a/hw/mcu/sony/cxd56/tools/flash_writer.py +++ b/hw/mcu/sony/cxd56/tools/flash_writer.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python3 +#!/usr/bin/env python3 # Copyright (C) 2018 Sony Semiconductor Solutions Corp. # diff --git a/hw/mcu/sony/cxd56/tools/xmodem.py b/hw/mcu/sony/cxd56/tools/xmodem.py old mode 100644 new mode 100755 index 60fcc952c..3ee2698f7 --- a/hw/mcu/sony/cxd56/tools/xmodem.py +++ b/hw/mcu/sony/cxd56/tools/xmodem.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ''' =============================== XMODEM file transfer protocol diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py old mode 100644 new mode 100755 index 55bec3d23..9bbc18850 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import click import ctypes import pandas as pd diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py old mode 100644 new mode 100755 index a569e7666..b2e17c8e3 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # # The MIT License (MIT) # diff --git a/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py b/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py old mode 100644 new mode 100755 index 00c0da8cc..a8e5b2726 --- a/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py +++ b/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py @@ -1,4 +1,4 @@ -#! python3 +#!/usr/bin/env python3 # ========================================== # Unity Project - A Test Framework for C # Copyright (c) 2015 Alexander Mueller / XelaRellum@web.de diff --git a/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py b/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py old mode 100644 new mode 100755 index 71dd56888..2379ad49a --- a/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py +++ b/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import sys import os from glob import glob diff --git a/tools/build.py b/tools/build.py old mode 100644 new mode 100755 index f9ae68231..1f3a7e0af --- a/tools/build.py +++ b/tools/build.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import argparse import random import os diff --git a/tools/build_utils.py b/tools/build_utils.py old mode 100644 new mode 100755 index 5f88db8a2..357a95c93 --- a/tools/build_utils.py +++ b/tools/build_utils.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import subprocess import pathlib import time diff --git a/tools/gen_doc.py b/tools/gen_doc.py old mode 100644 new mode 100755 index 668c77ef6..c69f3ff29 --- a/tools/gen_doc.py +++ b/tools/gen_doc.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import pandas as pd from tabulate import tabulate from pathlib import Path diff --git a/tools/get_deps.py b/tools/get_deps.py old mode 100644 new mode 100755 index 06da54b41..84c6a9e61 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import argparse import sys import subprocess diff --git a/tools/iar_gen.py b/tools/iar_gen.py old mode 100644 new mode 100755 index ebcfa1423..8d45659db --- a/tools/iar_gen.py +++ b/tools/iar_gen.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/env python3 import os import sys diff --git a/tools/make_release.py b/tools/make_release.py old mode 100644 new mode 100755 index 3e653c12d..92c75baf9 --- a/tools/make_release.py +++ b/tools/make_release.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import re import gen_doc diff --git a/tools/mksunxi.py b/tools/mksunxi.py old mode 100644 new mode 100755 diff --git a/tools/pcapng_to_corpus.py b/tools/pcapng_to_corpus.py index 9c31365eb..3089f0bb6 100755 --- a/tools/pcapng_to_corpus.py +++ b/tools/pcapng_to_corpus.py @@ -1,4 +1,4 @@ -#!/bin/python3 +#!/usr/bin/env python3 import argparse import pcapng import zipfile -- cgit v1.3.1 From 40b55170c87da109b3416ac80eaa55ca56eadc77 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 18 Sep 2024 20:27:34 +0700 Subject: skip pico2 dual test, it seems not stable --- test/hil/hil_test.py | 1 + test/hil/rpi.json | 1 + 2 files changed, 2 insertions(+) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index a569e7666..ec28328d4 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -411,6 +411,7 @@ def test_board(board): for skip in board_tests['skip']: if skip in test_list: test_list.remove(skip) + print(f'{name:25} {skip:30} ... Skip') err_count = 0 for test in test_list: diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 77919f346..672e857fd 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -59,6 +59,7 @@ "flasher_sn": "E6633861A3978538", "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2350.cfg -c \"adapter speed 5000\"", "tests": { + "skip": ["dual/host_info_to_device_cdc"], "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "533D004242"}] } }, -- cgit v1.3.1 From 86b4608365e66ba250cf4fb52226b0ed02488cc1 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 24 Sep 2024 17:38:31 +0700 Subject: update dfifo allocation scheme to use top pointer, update document and explanation for EPInfo address and GDFIFO. some function rename update h743 linker to use SRAM1 since USB DMA cannot access DTCM ram update xmc4500 to use uuid for testing --- hw/bsp/stm32h7/linker/stm32h743xx_flash.ld | 35 +-- hw/bsp/xmc4000/family.c | 6 + src/portable/synopsys/dwc2/dcd_dwc2.c | 361 ++++++++++++++--------------- src/portable/synopsys/dwc2/dwc2_type.h | 14 +- 4 files changed, 206 insertions(+), 210 deletions(-) diff --git a/hw/bsp/stm32h7/linker/stm32h743xx_flash.ld b/hw/bsp/stm32h7/linker/stm32h743xx_flash.ld index 336afc01f..ba18c8cd1 100644 --- a/hw/bsp/stm32h7/linker/stm32h743xx_flash.ld +++ b/hw/bsp/stm32h7/linker/stm32h743xx_flash.ld @@ -32,23 +32,24 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = 0x20020000; /* end of RAM */ -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x200; /* required amount of heap */ -_Min_Stack_Size = 0x400; /* required amount of stack */ - /* Specify the memory areas */ MEMORY { -DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K -RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K -RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K -RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K -ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K -FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K + DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K + RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K + RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K + RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K + ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + /* Define output sections */ SECTIONS { @@ -127,7 +128,7 @@ SECTIONS . = ALIGN(4); _edata = .; /* define a global symbol at data end */ - } >DTCMRAM AT> FLASH + } >RAM_D1 AT> FLASH /* Uninitialized data section */ @@ -144,7 +145,9 @@ SECTIONS . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; - } >DTCMRAM + } >RAM_D1 + + /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : @@ -155,9 +158,7 @@ SECTIONS . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); - } >DTCMRAM - - + } >RAM_D1 /* Remove information from the standard libraries */ /DISCARD/ : diff --git a/hw/bsp/xmc4000/family.c b/hw/bsp/xmc4000/family.c index 88810de7a..c776cb58a 100644 --- a/hw/bsp/xmc4000/family.c +++ b/hw/bsp/xmc4000/family.c @@ -103,6 +103,12 @@ uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == XMC_GPIO_GetInput(BUTTON_PIN); } +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + uint8_t const len = tu_min8(16, max_len); + memcpy(id, g_chipid, len); + return len; +} + int board_uart_read(uint8_t* buf, int len) { #ifdef UART_DEV for(int i=0;igrxfsiz -static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs) +static uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type +static uint16_t _dfifo_top; // top free location in FIFO RAM // Number of IN endpoints active static uint8_t _allocated_ep_in_count; @@ -92,68 +90,125 @@ static uint8_t _allocated_ep_in_count; // SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by static bool _sof_en; -// Calculate the RX FIFO size according to minimum recommendations from reference manual -// RxFIFO = (5 * number of control endpoints + 8) + -// ((largest USB packet used / 4) + 1 for status information) + -// (2 * number of OUT endpoints) + 1 for Global NAK -// with number of control endpoints = 1 we have -// RxFIFO = 15 + (largest USB packet used / 4) + 2 * number of OUT endpoints -// we double the largest USB packet size to be able to hold up to 2 packets -static inline uint16_t calc_grxfsiz(uint16_t max_ep_size, uint8_t ep_count) { - return 15 + 2 * (max_ep_size / 4) + 2 * ep_count; +//-------------------------------------------------------------------- +// DMA +//-------------------------------------------------------------------- + +TU_ATTR_ALWAYS_INLINE static inline bool dma_enabled(const dwc2_regs_t* dwc2) { + (void) dwc2; + // DMA doesn't support fifo transfer +#ifdef TUD_AUDIO_PREFER_RING_BUFFER +#if TUD_AUDIO_PREFER_RING_BUFFER + return false; +#endif +#endif + // Internal DMA only + return (dwc2->ghwcfg2_bm.arch == GHWCFG2_ARCH_INTERNAL_DMA); + // return false; +} + +TU_ATTR_ALWAYS_INLINE static inline uint16_t dma_cal_epfifo_base(uint8_t rhport) { + // Scatter/Gather DMA mode is not yet supported. Buffer DMA only need 1 words per endpoint direction + const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; + return dwc2_controller->ep_fifo_size/4 - 2*dwc2_controller->ep_count; } -TU_ATTR_ALWAYS_INLINE static inline void fifo_flush_tx(dwc2_regs_t* dwc2, uint8_t epnum) { +static void dma_setup_prepare(uint8_t rhport) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + + if (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a) { + if(dwc2->epout[0].doepctl & DOEPCTL_EPENA) { + return; + } + } + + // Receive only 1 packet + dwc2->epout[0].doeptsiz = (1 << DOEPTSIZ_STUPCNT_Pos) | (1 << DOEPTSIZ_PKTCNT_Pos) | (8 << DOEPTSIZ_XFRSIZ_Pos); + dwc2->epout[0].doepdma = (uintptr_t)_setup_packet; + dwc2->epout[0].doepctl |= DOEPCTL_EPENA | DOEPCTL_USBAEP; +} + +//--------------------------------------------------------------------+ +// Data FIFO +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_tx(dwc2_regs_t* dwc2, uint8_t epnum) { // flush TX fifo and wait for it cleared dwc2->grstctl = GRSTCTL_TXFFLSH | (epnum << GRSTCTL_TXFNUM_Pos); while (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) {} } -TU_ATTR_ALWAYS_INLINE static inline void fifo_flush_rx(dwc2_regs_t* dwc2) { +TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_rx(dwc2_regs_t* dwc2) { // flush RX fifo and wait for it cleared dwc2->grstctl = GRSTCTL_RXFFLSH; while (dwc2->grstctl & GRSTCTL_RXFFLSH_Msk) {} } -static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { +/* USB Data FIFO Layout + + The FIFO is split up into + - EPInfo: for storing DMA metadata, only required when use DMA. Maximum size is called + EP_LOC_CNT = ep_fifo_size - ghwcfg3.dfifo_depth. For value less than EP_LOC_CNT, gdfifocfg must be configured before + gahbcfg.dmaen is set + - Buffer mode: 1 word per endpoint direction + - Scatter/Gather DMA: 4 words per endpoint direction + - TX FIFO: one fifo for each IN endpoint. Size is dynamic depending on packet size, starting from top with EP0 IN. + - Shared RX FIFO: a shared fifo for all OUT endpoints. Typically, can hold up to 2 packets of the largest EP size. + + We allocated TX FIFO from top to bottom (using top pointer), this to allow the RX FIFO to grow dynamically which is + possible since the free space is located between the RX and TX FIFOs. + + ---------------- ep_fifo_size + | EPInfo | + | for DMA | + |-------------|-- gdfifocfg.EPINFOBASE (max is ghwcfg3.dfifo_depth) + | IN FIFO 0 | + | control | + |-------------| + | IN FIFO 1 | + |-------------| + | . . . . | + |-------------| + | IN FIFO n | + |-------------| + | FREE | + |-------------|-- GRXFSIZ (expandable) + | OUT FIFO | + | ( Shared ) | + --------------- 0 + + According to "FIFO RAM allocation" section in RM, FIFO RAM are allocated as follows (each word 32-bits): + - Each EP IN needs at least max packet size + - All EP OUT shared a unique OUT FIFO which uses (for Slave or Buffer DMA, Scatt/Gather DMA use different formula): + - 13 for setup packets + control words (up to 3 setup packets). + - 1 for global NAK (not required/used here). + - Largest-EPsize / 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4) + 1" + - 2 for each used OUT endpoint + + Therefore GRXFSIZ = 13 + 1 + 2 x (Largest-EPsize/4 + 1) + 2 x EPOUTnum +*/ + +TU_ATTR_ALWAYS_INLINE static inline uint16_t calc_grxfsiz(uint16_t largest_ep_size, uint8_t ep_count) { + return 13 + 1 + 2 * ((largest_ep_size / 4) + 1) + 2 * ep_count; +} + +static bool dfifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const ep_count = _dwc2_controller[rhport].ep_count; + const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; + uint8_t const ep_count = dwc2_controller->ep_count; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); TU_ASSERT(epnum < ep_count); uint16_t fifo_size = tu_div_ceil(packet_size, 4); - - // "USB Data FIFOs" section in reference manual - // Peripheral FIFO architecture - // - // --------------- 320 or 1024 ( 1280 or 4096 bytes ) - // | IN FIFO 0 | - // --------------- (320 or 1024) - 16 - // | IN FIFO 1 | - // --------------- (320 or 1024) - 16 - x - // | . . . . | - // --------------- (320 or 1024) - 16 - x - y - ... - z - // | IN FIFO MAX | - // --------------- - // | FREE | - // --------------- GRXFSIZ - // | OUT FIFO | - // | ( Shared ) | - // --------------- 0 - // - // In FIFO is allocated by following rules: - // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". if (dir == TUSB_DIR_OUT) { // Calculate required size of RX FIFO - uint16_t const sz = calc_grxfsiz(4 * fifo_size, ep_count); + uint16_t const new_sz = calc_grxfsiz(4 * fifo_size, ep_count); - // If size_rx needs to be extended check if possible and if so enlarge it - if (dwc2->grxfsiz < sz) { - TU_ASSERT(sz + _allocated_fifo_words_tx <= _dwc2_controller[rhport].ep_fifo_size / 4); - - // Enlarge RX FIFO - dwc2->grxfsiz = sz; + // If size_rx needs to be extended check if there is enough free space + if (dwc2->grxfsiz < new_sz) { + TU_ASSERT(new_sz <= _dfifo_top); + dwc2->grxfsiz = new_sz; // Enlarge RX FIFO } } else { // Check IN endpoints concurrently active limit @@ -162,59 +217,48 @@ static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { _allocated_ep_in_count++; } - // Note if The TXFELVL is configured as half empty. In order - // to be able to write a packet at that point, the fifo must be twice the max_size. + // If The TXFELVL is configured as half empty, the fifo must be twice the max_size. if ((dwc2->gahbcfg & GAHBCFG_TXFELVL) == 0) { fifo_size *= 2; } // Check if free space is available - TU_ASSERT(_allocated_fifo_words_tx + fifo_size + dwc2->grxfsiz <= _dwc2_controller[rhport].ep_fifo_size / 4); - _allocated_fifo_words_tx += fifo_size; - TU_LOG(DWC2_DEBUG, " Allocated %u bytes at offset %" PRIu32, fifo_size * 4, - _dwc2_controller[rhport].ep_fifo_size - _allocated_fifo_words_tx * 4); + TU_ASSERT(_dfifo_top >= fifo_size + dwc2->grxfsiz); + _dfifo_top -= fifo_size; + TU_LOG(DWC2_DEBUG, " TX FIFO %u: allocated %u words at offset %u\r\n", epnum, fifo_size, _dfifo_top); - // DIEPTXF starts at FIFO #1. // Both TXFD and TXSA are in unit of 32-bit words. - dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | - (_dwc2_controller[rhport].ep_fifo_size / 4 - _allocated_fifo_words_tx); + if (epnum == 0) { + dwc2->dieptxf0 = (fifo_size << DIEPTXF0_TX0FD_Pos) | _dfifo_top; + } else { + // DIEPTXF starts at FIFO #1. + dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | _dfifo_top; + } } return true; } -static inline bool dma_enabled(uint8_t rhport) -{ - // DMA doesn't support fifo transfer -#ifdef TUD_AUDIO_PREFER_RING_BUFFER -#if TUD_AUDIO_PREFER_RING_BUFFER - return false; -#endif -#endif - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - // Internal DMA only - return (dwc2->ghwcfg2_bm.arch == 2); -} - -static void dma_stpkt_rx(uint8_t rhport) -{ +static void dfifo_init(uint8_t rhport) { + const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; dwc2_regs_t* dwc2 = DWC2_REG(rhport); + dwc2->grxfsiz = calc_grxfsiz(CFG_TUD_ENDPOINT0_SIZE, dwc2_controller->ep_count); - if (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a) { - if(dwc2->epout[0].doepctl & DOEPCTL_EPENA) - return; + if(dma_enabled(dwc2)) { + // DMA use last DFIFO to store metadata + _dfifo_top = dma_cal_epfifo_base(rhport); + }else { + _dfifo_top = dwc2_controller->ep_fifo_size / 4; } - // Receive only 1 packet - dwc2->epout[0].doeptsiz = 0; - dwc2->epout[0].doeptsiz |= (1 << DOEPTSIZ_STUPCNT_Pos); - dwc2->epout[0].doeptsiz |= 8; - dwc2->epout[0].doeptsiz |= (1 << DOEPTSIZ_PKTCNT_Pos); - dwc2->epout[0].doepdma = (uintptr_t)_setup_packet; - - dwc2->epout[0].doepctl |= DOEPCTL_EPENA | DOEPCTL_USBAEP; + // Allocate FIFO for EP0 IN + dfifo_alloc(rhport, 0x80, CFG_TUD_ENDPOINT0_SIZE); } +//-------------------------------------------------------------------- +// Endpoint +//-------------------------------------------------------------------- + static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); @@ -235,7 +279,7 @@ static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoin dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); } else { dwc2->epin[epnum].diepctl = dxepctl | (epnum << DIEPCTL_TXFNUM_Pos); - dwc2->daintmsk |= (1 << (DAINTMSK_IEPM_Pos + epnum)); + dwc2->daintmsk |= TU_BIT(DAINTMSK_IEPM_Pos + epnum); } } @@ -265,7 +309,7 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) { } // Flush the FIFO, and wait until we have confirmed it cleared. - fifo_flush_tx(dwc2, epnum); + dfifo_flush_tx(dwc2, epnum); } else { dwc2_epout_t* epout = dwc2->epout; @@ -318,88 +362,27 @@ static void bus_reset(uint8_t rhport) { } } - fifo_flush_tx(dwc2, 0x10); // all tx fifo - fifo_flush_rx(dwc2); + dfifo_flush_tx(dwc2, 0x10); // all tx fifo + dfifo_flush_rx(dwc2); // 3. Set up interrupt mask dwc2->daintmsk = TU_BIT(DAINTMSK_OEPM_Pos) | TU_BIT(DAINTMSK_IEPM_Pos); dwc2->doepmsk = DOEPMSK_STUPM | DOEPMSK_XFRCM; dwc2->diepmsk = DIEPMSK_TOM | DIEPMSK_XFRCM; - // "USB Data FIFOs" section in reference manual - // Peripheral FIFO architecture - // - // The FIFO is split up in a lower part where the RX FIFO is located and an upper part where the TX FIFOs start. - // We do this to allow the RX FIFO to grow dynamically which is possible since the free space is located - // between the RX and TX FIFOs. This is required by ISO OUT EPs which need a bigger FIFO than the standard - // configuration done below. - // - // Dynamically FIFO sizes are of interest only for ISO EPs since all others are usually not opened and closed. - // All EPs other than ISO are opened as soon as the driver starts up i.e. when the host sends a - // configure interface command. Hence, all IN EPs other the ISO will be located at the top. IN ISO EPs are usually - // opened when the host sends an additional command: setInterface. At this point in time - // the ISO EP will be located next to the free space and can change its size. In case more IN EPs change its size - // an additional memory - // - // --------------- 320 or 1024 ( 1280 or 4096 bytes ) - // | IN FIFO 0 | - // --------------- (320 or 1024) - 16 - // | IN FIFO 1 | - // --------------- (320 or 1024) - 16 - x - // | . . . . | - // --------------- (320 or 1024) - 16 - x - y - ... - z - // | IN FIFO MAX | - // --------------- - // | FREE | - // --------------- GRXFSIZ - // | OUT FIFO | - // | ( Shared ) | - // --------------- 0 - // - // According to "FIFO RAM allocation" section in RM, FIFO RAM are allocated as follows (each word 32-bits): - // - Each EP IN needs at least max packet size, 16 words is sufficient for EP0 IN - // - // - All EP OUT shared a unique OUT FIFO which uses - // - 13 for setup packets + control words (up to 3 setup packets). - // - 1 for global NAK (not required/used here). - // - Largest-EPsize / 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4) + 1" - // - 2 for each used OUT endpoint - // - // Therefore GRXFSIZ = 13 + 1 + 1 + 2 x (Largest-EPsize/4) + 2 x EPOUTnum - // - FullSpeed (64 Bytes ): GRXFSIZ = 15 + 2 x 16 + 2 x ep_count = 47 + 2 x ep_count - // - Highspeed (512 bytes): GRXFSIZ = 15 + 2 x 128 + 2 x ep_count = 271 + 2 x ep_count - // - // NOTE: Largest-EPsize & EPOUTnum is actual used endpoints in configuration. Since DCD has no knowledge - // of the overall picture yet. We will use the worst scenario: largest possible + ep_count - // - // For Isochronous, largest EP size can be 1023/1024 for FS/HS respectively. In addition if multiple ISO - // are enabled at least "2 x (Largest-EPsize/4) + 1" are recommended. Maybe provide a macro for application to - // overwrite this. - - // EP0 out max is 64 - dwc2->grxfsiz = calc_grxfsiz(64, ep_count); - - // Setup the control endpoint 0 - _allocated_fifo_words_tx = 16; - - // DMA needs extra space for processing - if(dma_enabled(rhport)) { - uint16_t reserved = _dwc2_controller[rhport].ep_fifo_size / 4- dwc2->ghwcfg3_bm.total_fifo_size; - _allocated_fifo_words_tx += reserved; - } - - // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) - dwc2->dieptxf0 = (16 << DIEPTXF0_TX0FD_Pos) | (_dwc2_controller[rhport].ep_fifo_size / 4 - _allocated_fifo_words_tx); + dfifo_init(rhport); // Fixed control EP0 size to 64 bytes dwc2->epin[0].diepctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos); + dwc2->epout[0].doepctl &= ~(0x03 << DOEPCTL_MPSIZ_Pos); + xfer_status[0][TUSB_DIR_OUT].max_size = 64; xfer_status[0][TUSB_DIR_IN].max_size = 64; - dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); - - if(dma_enabled(rhport)) { - dma_stpkt_rx(rhport); + if(dma_enabled(dwc2)) { + dma_setup_prepare(rhport); + } else { + dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); } dwc2->gintmsk |= GINTMSK_OEPINT | GINTMSK_IEPINT; @@ -427,7 +410,7 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c epin[epnum].dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) | ((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk); - if(dma_enabled(rhport)) { + if(dma_enabled(dwc2)) { epin[epnum].diepdma = (uintptr_t)xfer->buffer; // For ISO endpoint set correct odd/even bit for next frame. @@ -468,7 +451,7 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c epout[epnum].doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk); } - if(dma_enabled(rhport)) { + if(dma_enabled(dwc2)) { epout[epnum].doepdma = (uintptr_t)xfer->buffer; } @@ -599,7 +582,9 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { // XCVRDLY: transceiver delay between xcvr_sel and txvalid during device chirp is required // when using with some PHYs such as USB334x (USB3341, USB3343, USB3346, USB3347) - if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) dcfg |= DCFG_XCVRDLY; + if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) { + dcfg |= DCFG_XCVRDLY; + } dwc2->dcfg = dcfg; } @@ -625,12 +610,9 @@ void dcd_init(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Check Synopsys ID register, failed if controller clock/power is not enabled - if (!check_dwc2(dwc2)) return; + TU_ASSERT(check_dwc2(dwc2), ); dcd_disconnect(rhport); - // max number of endpoints & total_fifo_size are: - // hw_cfg2->num_dev_ep, hw_cfg2->total_fifo_size - if (phy_hs_supported(dwc2)) { phy_hs_init(dwc2); // Highspeed } else { @@ -660,8 +642,8 @@ void dcd_init(uint8_t rhport) { // (non zero-length packet), send STALL back and discard. dwc2->dcfg |= DCFG_NZLSOHSK; - fifo_flush_tx(dwc2, 0x10); // all tx fifo - fifo_flush_rx(dwc2); + dfifo_flush_tx(dwc2, 0x10); // all tx fifo + dfifo_flush_rx(dwc2); // Clear all interrupts uint32_t int_mask = dwc2->gintsts; @@ -670,20 +652,24 @@ void dcd_init(uint8_t rhport) { dwc2->gotgint |= int_mask; // Required as part of core initialization. - dwc2->gintmsk = GINTMSK_OTGINT | GINTMSK_RXFLVLM | - GINTMSK_USBSUSPM | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM; + dwc2->gintmsk = GINTMSK_OTGINT | GINTMSK_USBSUSPM | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM; // Configure TX FIFO empty level for interrupt. Default is complete empty dwc2->gahbcfg |= GAHBCFG_TXFELVL; - // Enable global interrupt - dwc2->gahbcfg |= GAHBCFG_GINT; + if (dma_enabled(dwc2)) { + const uint16_t epinfo_base = dma_cal_epfifo_base(rhport); + dwc2->gdfifocfg = (epinfo_base << GDFIFOCFG_EPINFOBASE_SHIFT) | epinfo_base; - if (dma_enabled(rhport)) { + // DMA seems to be only settable after a core reset dwc2->gahbcfg |= GAHBCFG_DMAEN | GAHBCFG_HBSTLEN_2; - dwc2->gintmsk &=~GINTMSK_RXFLVLM; + }else { + dwc2->gintmsk |= GINTMSK_RXFLVLM; } + // Enable global interrupt + dwc2->gahbcfg |= GAHBCFG_GINT; + // make sure we are in device mode // TU_ASSERT(!(dwc2->gintsts & GINTSTS_CMOD), ); @@ -783,7 +769,7 @@ void dcd_sof_enable(uint8_t rhport, bool en) { *------------------------------------------------------------------*/ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { - TU_ASSERT(fifo_alloc(rhport, desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt))); + TU_ASSERT(dfifo_alloc(rhport, desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt))); edpt_activate(rhport, desc_edpt); return true; } @@ -812,32 +798,21 @@ void dcd_edpt_close_all(uint8_t rhport) { xfer_status[n][TUSB_DIR_IN].max_size = 0; } - // reset allocated fifo OUT - dwc2->grxfsiz = calc_grxfsiz(64, ep_count); - // reset allocated fifo IN - _allocated_fifo_words_tx = 16; - - fifo_flush_tx(dwc2, 0x10); // all tx fifo - fifo_flush_rx(dwc2); + dfifo_flush_tx(dwc2, 0x10); // all tx fifo + dfifo_flush_rx(dwc2); - // DMA needs extra space for processing - if(dma_enabled(rhport)) { - uint16_t reserved = _dwc2_controller[rhport].ep_fifo_size / 4- dwc2->ghwcfg3_bm.total_fifo_size; - _allocated_fifo_words_tx += reserved; - } + dfifo_init(rhport); // re-init dfifo } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { - TU_ASSERT(fifo_alloc(rhport, ep_addr, largest_packet_size)); + TU_ASSERT(dfifo_alloc(rhport, ep_addr, largest_packet_size)); return true; } bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { // Disable EP to clear potential incomplete transfers edpt_disable(rhport, p_endpoint_desc->bEndpointAddress, false); - edpt_activate(rhport, p_endpoint_desc); - return true; } @@ -904,8 +879,8 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { edpt_disable(rhport, ep_addr, true); - if((tu_edpt_number(ep_addr) == 0) && dma_enabled(rhport)) { - dma_stpkt_rx(rhport); + if((tu_edpt_number(ep_addr) == 0) && dma_enabled(DWC2_REG(rhport))) { + dma_setup_prepare(rhport); } } @@ -1075,13 +1050,15 @@ static void handle_epout_irq(uint8_t rhport) { uint32_t const doepint = epout->doepint; + TU_ASSERT((epout->doepint & DOEPINT_AHBERR) == 0, ); + // OUT XFER complete if (epout->doepint & DOEPINT_XFRC) { epout->doepint = DOEPINT_XFRC; xfer_ctl_t* xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); - if(dma_enabled(rhport)) { + if(dma_enabled(dwc2)) { if (doepint & DOEPINT_STUP) { // STPKTRX is only available for version from 3_00a if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { @@ -1103,7 +1080,7 @@ static void handle_epout_irq(uint8_t rhport) { xfer->total_len -= remain; // this is ZLP, so prepare EP0 for next setup if(n == 0 && xfer->total_len == 0) { - dma_stpkt_rx(rhport); + dma_setup_prepare(rhport); } dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); @@ -1135,8 +1112,8 @@ static void handle_epout_irq(uint8_t rhport) { if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { epout->doepint = DOEPINT_STPKTRX; } - if(dma_enabled(rhport) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - dma_stpkt_rx(rhport); + if(dma_enabled(dwc2) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + dma_setup_prepare(rhport); } dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true); @@ -1165,8 +1142,8 @@ static void handle_epin_irq(uint8_t rhport) { // Schedule another packet to be transmitted. edpt_schedule_packets(rhport, n, TUSB_DIR_IN, 1, ep0_pending[TUSB_DIR_IN]); } else { - if((n == 0) && dma_enabled(rhport)) { - dma_stpkt_rx(rhport); + if((n == 0) && dma_enabled(dwc2)) { + dma_setup_prepare(rhport); } dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); } diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index 244323b51..c21bf9e94 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -100,6 +100,12 @@ enum { FS_PHY_TYPE_ULPI, }; +enum { + GHWCFG2_ARCH_SLAVE_ONLY = 0, + GHWCFG2_ARCH_EXTERNAL_DMA, // 1 + GHWCFG2_ARCH_INTERNAL_DMA, // 2 +}; + typedef struct TU_ATTR_PACKED { uint32_t op_mode : 3; // 0: HNP and SRP | 1: SRP | 2: non-HNP, non-SRP @@ -134,7 +140,7 @@ typedef struct TU_ATTR_PACKED uint32_t otg_enable_hsic : 1; // 1: HSIC-capable with shared UTMI PHY interface | 0: non-HSIC uint32_t battery_charger_support : 1; // support battery charger uint32_t lpm_mode : 1; // LPC mode - uint32_t total_fifo_size : 16; // DFIFO depth value in terms of 32-bit words + uint32_t dfifo_depth : 16; // DFIFO depth - EP_LOC_CNT in terms of 32-bit words }dwc2_ghwcfg3_t; TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg3_t) == 4, "incorrect size"); @@ -1240,6 +1246,12 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define GLPMCFG_ENBESL_Msk (0x1UL << GLPMCFG_ENBESL_Pos) // 0x10000000 #define GLPMCFG_ENBESL GLPMCFG_ENBESL_Msk // Enable best effort service latency +// GDFIFOCFG +#define GDFIFOCFG_EPINFOBASE_MASK (0xffff << 16) +#define GDFIFOCFG_EPINFOBASE_SHIFT 16 +#define GDFIFOCFG_GDFIFOCFG_MASK (0xffff << 0) +#define GDFIFOCFG_GDFIFOCFG_SHIFT 0 + /******************** Bit definition for DIEPEACHMSK1 register ********************/ #define DIEPEACHMSK1_XFRCM_Pos (0U) #define DIEPEACHMSK1_XFRCM_Msk (0x1UL << DIEPEACHMSK1_XFRCM_Pos) // 0x00000001 -- cgit v1.3.1 From a1244381b3e68959f99bc0ba8057eea5ca35bac6 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 24 Sep 2024 17:55:15 +0700 Subject: add CFG_TUD_DWC2_DMA, make it compile time option --- src/common/tusb_mcu.h | 2 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 9 +++----- src/tusb_option.h | 39 +++++++++++++++++++++-------------- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 0a4462a0a..6ead1ea0b 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -524,7 +524,7 @@ #define TUP_DCD_EDPT_ISO_ALLOC #endif -#if defined(TUP_USBIP_DWC2) +#if defined(TUP_USBIP_DWC2) // && CFG_TUD_DWC2_DMA == 0 #define TUP_MEM_CONST_ADDR #endif diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 897f81a42..2c5e82778 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -95,16 +95,13 @@ static bool _sof_en; //-------------------------------------------------------------------- TU_ATTR_ALWAYS_INLINE static inline bool dma_enabled(const dwc2_regs_t* dwc2) { + #if !CFG_TUD_DWC2_DMA (void) dwc2; - // DMA doesn't support fifo transfer -#ifdef TUD_AUDIO_PREFER_RING_BUFFER -#if TUD_AUDIO_PREFER_RING_BUFFER return false; -#endif -#endif + #else // Internal DMA only return (dwc2->ghwcfg2_bm.arch == GHWCFG2_ARCH_INTERNAL_DMA); - // return false; + #endif } TU_ATTR_ALWAYS_INLINE static inline uint16_t dma_cal_epfifo_base(uint8_t rhport) { diff --git a/src/tusb_option.h b/src/tusb_option.h index fb0209023..e61b3bb9e 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -228,7 +228,7 @@ #define OPT_MODE_SPEED_MASK 0xff00 //--------------------------------------------------------------------+ -// Include tusb_config.h and tusb_mcu.h +// Include tusb_config.h //--------------------------------------------------------------------+ // Allow to use command line to change the config name/location @@ -238,6 +238,29 @@ #include "tusb_config.h" #endif +//--------------------------------------------------------------------+ +// USBIP +//--------------------------------------------------------------------+ + +// DWC2 controller: use DMA for data transfer +#ifndef CFG_TUD_DWC2_DMA + #define CFG_TUD_DWC2_DMA 1 +#endif + +// Enable PIO-USB software host controller +#ifndef CFG_TUH_RPI_PIO_USB + #define CFG_TUH_RPI_PIO_USB 0 +#endif + +#ifndef CFG_TUD_RPI_PIO_USB + #define CFG_TUD_RPI_PIO_USB 0 +#endif + +// MAX3421 Host controller option +#ifndef CFG_TUH_MAX3421 + #define CFG_TUH_MAX3421 0 +#endif + #include "common/tusb_mcu.h" //-------------------------------------------------------------------- @@ -548,20 +571,6 @@ #define CFG_TUH_API_EDPT_XFER 0 #endif -// Enable PIO-USB software host controller -#ifndef CFG_TUH_RPI_PIO_USB - #define CFG_TUH_RPI_PIO_USB 0 -#endif - -#ifndef CFG_TUD_RPI_PIO_USB - #define CFG_TUD_RPI_PIO_USB 0 -#endif - -// MAX3421 Host controller option -#ifndef CFG_TUH_MAX3421 - #define CFG_TUH_MAX3421 0 -#endif - //--------------------------------------------------------------------+ // TypeC Options (Default) //--------------------------------------------------------------------+ -- cgit v1.3.1 From 6a15e7875c6bc42247210fdcebdea1a4353c51ea Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 24 Sep 2024 18:01:09 +0700 Subject: more rename --- src/portable/synopsys/dwc2/dcd_dwc2.c | 106 +++++++++++++++++----------------- src/tusb_option.h | 2 +- 2 files changed, 55 insertions(+), 53 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 2c5e82778..eb5b145e8 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -252,6 +252,55 @@ static void dfifo_init(uint8_t rhport) { dfifo_alloc(rhport, 0x80, CFG_TUD_ENDPOINT0_SIZE); } +// Read a single data packet from receive FIFO +static void dfifo_read_packet(uint8_t rhport, uint8_t* dst, uint16_t len) { + (void) rhport; + + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + volatile const uint32_t* rx_fifo = dwc2->fifo[0]; + + // Reading full available 32 bit words from fifo + uint16_t full_words = len >> 2; + while (full_words--) { + tu_unaligned_write32(dst, *rx_fifo); + dst += 4; + } + + // Read the remaining 1-3 bytes from fifo + uint8_t const bytes_rem = len & 0x03; + if (bytes_rem != 0) { + uint32_t const tmp = *rx_fifo; + dst[0] = tu_u32_byte0(tmp); + if (bytes_rem > 1) dst[1] = tu_u32_byte1(tmp); + if (bytes_rem > 2) dst[2] = tu_u32_byte2(tmp); + } +} + +// Write a single data packet to EPIN FIFO +static void dfifo_write_packet(uint8_t rhport, uint8_t fifo_num, uint8_t const* src, uint16_t len) { + (void) rhport; + + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + volatile uint32_t* tx_fifo = dwc2->fifo[fifo_num]; + + // Pushing full available 32 bit words to fifo + uint16_t full_words = len >> 2; + while (full_words--) { + *tx_fifo = tu_unaligned_read32(src); + src += 4; + } + + // Write the remaining 1-3 bytes into fifo + uint8_t const bytes_rem = len & 0x03; + if (bytes_rem) { + uint32_t tmp_word = src[0]; + if (bytes_rem > 1) tmp_word |= (src[1] << 8); + if (bytes_rem > 2) tmp_word |= (src[2] << 16); + + *tx_fifo = tmp_word; + } +} + //-------------------------------------------------------------------- // Endpoint //-------------------------------------------------------------------- @@ -899,56 +948,9 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { } } -/*------------------------------------------------------------------*/ - -// Read a single data packet from receive FIFO -static void read_fifo_packet(uint8_t rhport, uint8_t* dst, uint16_t len) { - (void) rhport; - - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - volatile const uint32_t* rx_fifo = dwc2->fifo[0]; - - // Reading full available 32 bit words from fifo - uint16_t full_words = len >> 2; - while (full_words--) { - tu_unaligned_write32(dst, *rx_fifo); - dst += 4; - } - - // Read the remaining 1-3 bytes from fifo - uint8_t const bytes_rem = len & 0x03; - if (bytes_rem != 0) { - uint32_t const tmp = *rx_fifo; - dst[0] = tu_u32_byte0(tmp); - if (bytes_rem > 1) dst[1] = tu_u32_byte1(tmp); - if (bytes_rem > 2) dst[2] = tu_u32_byte2(tmp); - } -} - -// Write a single data packet to EPIN FIFO -static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t const* src, uint16_t len) { - (void) rhport; - - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - volatile uint32_t* tx_fifo = dwc2->fifo[fifo_num]; - - // Pushing full available 32 bit words to fifo - uint16_t full_words = len >> 2; - while (full_words--) { - *tx_fifo = tu_unaligned_read32(src); - src += 4; - } - - // Write the remaining 1-3 bytes into fifo - uint8_t const bytes_rem = len & 0x03; - if (bytes_rem) { - uint32_t tmp_word = src[0]; - if (bytes_rem > 1) tmp_word |= (src[1] << 8); - if (bytes_rem > 2) tmp_word |= (src[2] << 16); - - *tx_fifo = tmp_word; - } -} +//-------------------------------------------------------------------- +// Interrupt Handler +//-------------------------------------------------------------------- static void handle_rxflvl_irq(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); @@ -1002,7 +1004,7 @@ static void handle_rxflvl_irq(uint8_t rhport) { tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void*) (uintptr_t) rx_fifo, bcnt); } else { // Linear buffer - read_fifo_packet(rhport, xfer->buffer, bcnt); + dfifo_read_packet(rhport, xfer->buffer, bcnt); // Increment pointer to xfer data xfer->buffer += bcnt; @@ -1171,7 +1173,7 @@ static void handle_epin_irq(uint8_t rhport) { volatile uint32_t* tx_fifo = dwc2->fifo[n]; tu_fifo_read_n_const_addr_full_words(xfer->ff, (void*) (uintptr_t) tx_fifo, packet_size); } else { - write_fifo_packet(rhport, n, xfer->buffer, packet_size); + dfifo_write_packet(rhport, n, xfer->buffer, packet_size); // Increment pointer to xfer data xfer->buffer += packet_size; diff --git a/src/tusb_option.h b/src/tusb_option.h index e61b3bb9e..0d118eef9 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -244,7 +244,7 @@ // DWC2 controller: use DMA for data transfer #ifndef CFG_TUD_DWC2_DMA - #define CFG_TUD_DWC2_DMA 1 + #define CFG_TUD_DWC2_DMA 0 #endif // Enable PIO-USB software host controller -- cgit v1.3.1 From e483c6a2ade2dbf2ec44d835134f62eab0cf9698 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 24 Sep 2024 21:30:16 +0200 Subject: Add a note about data cache. --- src/tusb_option.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tusb_option.h b/src/tusb_option.h index 0d118eef9..17de9cd72 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -243,6 +243,10 @@ //--------------------------------------------------------------------+ // DWC2 controller: use DMA for data transfer +// For processors with data cache enabled, USB endpoint buffer region +// (defined by CFG_TUSB_MEM_SECTION) must be declared as non-cacheable. +// For example, on Cortex-M7 the MPU region can be configured as normal +// non-cacheable, with RASR register value: TEX=1 C=0 B=0 S=0. #ifndef CFG_TUD_DWC2_DMA #define CFG_TUD_DWC2_DMA 0 #endif -- cgit v1.3.1 From e209acb8d3624d3e6e6b6cee827bf4a97a4b138c Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Mon, 30 Sep 2024 10:58:19 +0700 Subject: Migrate hil vm (#2822) * migrate hil to new x64 VM instead of rpi * re-enable hil for s3 --- .github/workflows/build_util.yml | 18 +++++++ .github/workflows/hil_test.yml | 56 +++++++------------- test/hil/hil_test.py | 51 ++++++++++--------- test/hil/requirements.txt | 2 + test/hil/rpi.json | 107 --------------------------------------- test/hil/tinyusb.json | 107 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 173 insertions(+), 168 deletions(-) create mode 100644 test/hil/requirements.txt delete mode 100644 test/hil/rpi.json create mode 100644 test/hil/tinyusb.json diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index ff98aef2d..294d18140 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -16,6 +16,10 @@ on: required: false default: false type: boolean + upload-artifacts: + required: false + default: false + type: boolean os: required: false type: string @@ -62,3 +66,17 @@ jobs: python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} fi shell: bash + + - name: Upload Artifacts for Hardware Testing + if: ${{ inputs.upload-artifacts }} + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.arg }} + path: | + cmake-build/cmake-build-*/*/*/*.elf + cmake-build/cmake-build-*/*/*/*.bin + cmake-build/cmake-build-*/*/*/*.bin + cmake-build/cmake-build-*/*/*/bootloader/bootloader.bin + cmake-build/cmake-build-*/*/*/partition_table/partition-table.bin + cmake-build/cmake-build-*/*/*/config.env + cmake-build/cmake-build-*/*/*/flash_args diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index 087374be2..6ece44922 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -18,7 +18,7 @@ concurrency: cancel-in-progress: true env: - HIL_JSON: test/hil/rpi.json + HIL_JSON: test/hil/tinyusb.json jobs: set-matrix: @@ -32,7 +32,10 @@ jobs: - name: Generate matrix json id: set-matrix-json run: | - MATRIX_JSON=$(jq -c '{ "arm-gcc": [.boards[] | select(.flasher != "esptool" and .flasher != "openocd_wch") | .name] }' ${{ env.HIL_JSON }}) + MATRIX_ARMGCC=$(jq -c '{ "arm-gcc": { "family": [.boards[] | select(.flasher != "esptool" and .flasher != "openocd_wch") | "-b \(.name)"] } }' "${{ env.HIL_JSON }}") + MATRIX_ESP=$(jq -c '{ "esp-idf": { "family": [.boards[] | select(.flasher == "esptool") | "-b \(.name)"] } }' "${{ env.HIL_JSON }}") + MATRIX_RISCV=$(jq -c '{ "riscv-gcc": { "family": [.boards[] | select(.flasher == "openocd_wch") | "-b \(.name)"] } }' "${{ env.HIL_JSON }}") + MATRIX_JSON=$(jq -nc --argjson arm "$MATRIX_ARMGCC" --argjson esp "$MATRIX_ESP" --argjson riscv "$MATRIX_RISCV" '$arm + $esp + $riscv') echo "matrix=$MATRIX_JSON" echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT @@ -42,44 +45,28 @@ jobs: build: if: github.repository_owner == 'hathach' needs: set-matrix - runs-on: ubuntu-latest + uses: ./.github/workflows/build_util.yml strategy: fail-fast: false matrix: - board: ${{ fromJSON(needs.set-matrix.outputs.json)['arm-gcc'] }} - steps: - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Setup arm-gcc toolchain - uses: ./.github/actions/setup_toolchain - with: - toolchain: 'arm-gcc' - - - name: Get Dependencies - uses: ./.github/actions/get_deps - with: - arg: -b${{ matrix.board }} - - - name: Build - run: python tools/build.py -b${{ matrix.board }} - - - name: Upload Artifacts for Hardware Testing - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.board }} - path: | - cmake-build/cmake-build-*/*/*/*.elf - cmake-build/cmake-build-*/*/*/*.bin + toolchain: + - 'arm-gcc' + - 'esp-idf' + with: + build-system: 'cmake' + toolchain: ${{ matrix.toolchain }} + build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} + one-per-family: true + upload-artifacts: true # --------------------------------------- # Hardware in the loop (HIL) - # self-hosted running on an RPI. For attached hardware checkout test/hil/rpi.json + # self-hosted running on an VM. For attached hardware checkout test/hil/tinyusb.json # --------------------------------------- - hil-rpi: + hil-tinyusb: if: github.repository_owner == 'hathach' needs: build - runs-on: [self-hosted, ARM64, rpi, hardware-in-the-loop] + runs-on: [self-hosted, X64, hathach, hardware-in-the-loop] steps: - name: Clean workspace run: | @@ -87,13 +74,6 @@ jobs: rm -rf "${{ github.workspace }}" mkdir -p "${{ github.workspace }}" - # USB bus on rpi is not stable, reset it before testing -# - name: Reset USB bus -# run: | -# echo "1-2" | sudo tee /sys/bus/usb/drivers/usb/unbind -# sleep 5 -# echo "1-2" | sudo tee /sys/bus/usb/drivers/usb/bind - - name: Checkout TinyUSB uses: actions/checkout@v4 with: diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index ec28328d4..2d14220c5 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -45,6 +45,11 @@ STATUS_SKIPPED = "\033[33mSkipped\033[0m" verbose = False +# ------------------------------------------------------------- +# Path +# ------------------------------------------------------------- +OPENCOD_ADI_PATH = f'{os.getenv("HOME")}/app/openocd_adi' + # get usb serial by id def get_serial_dev(id, vendor_str, product_str, ifnum): if vendor_str and product_str: @@ -112,8 +117,8 @@ def read_disk_file(uid, lun, fname): # ------------------------------------------------------------- # Flashing firmware # ------------------------------------------------------------- -def run_cmd(cmd): - r = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) +def run_cmd(cmd, cwd=None): + r = subprocess.run(cmd, cwd=cwd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if r.returncode != 0: title = f'COMMAND FAILED: {cmd}' print() @@ -187,11 +192,7 @@ echo "Ready for Remote Connections" def flash_openocd_adi(board, firmware): - openocd_adi_script_path = f'{os.getenv("HOME")}/app/openocd_adi/tcl' - if not os.path.exists(openocd_adi_script_path): - openocd_adi_script_path = '/home/pi/openocd_adi/tcl' - - ret = run_cmd(f'openocd_adi -c "adapter serial {board["flasher_sn"]}" -s {openocd_adi_script_path} ' + ret = run_cmd(f'{OPENCOD_ADI_PATH}/src/openocd -c "adapter serial {board["flasher_sn"]}" -s {OPENCOD_ADI_PATH}/tcl ' f'{board["flasher_args"]} -c "program {firmware}.elf reset exit"') return ret @@ -203,14 +204,14 @@ def flash_wlink_rs(board, firmware): def flash_esptool(board, firmware): port = get_serial_dev(board["flasher_sn"], None, None, 0) - dir = os.path.dirname(f'{firmware}.bin') - with open(f'{dir}/config.env') as f: - IDF_TARGET = json.load(f)['IDF_TARGET'] - with open(f'{dir}/flash_args') as f: + fw_dir = os.path.dirname(f'{firmware}.bin') + with open(f'{fw_dir}/config.env') as f: + idf_target = json.load(f)['IDF_TARGET'] + with open(f'{fw_dir}/flash_args') as f: flash_args = f.read().strip().replace('\n', ' ') - command = (f'esptool.py --chip {IDF_TARGET} -p {port} {board["flasher_args"]} ' + command = (f'esptool.py --chip {idf_target} -p {port} {board["flasher_args"]} ' f'--before=default_reset --after=hard_reset write_flash {flash_args}') - ret = subprocess.run(command, shell=True, cwd=dir, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + ret = run_cmd(command, cwd=fw_dir) return ret @@ -305,8 +306,7 @@ def test_device_dfu(board): # Wait device enum timeout = ENUM_TIMEOUT while timeout: - ret = subprocess.run(f'dfu-util -l', - shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + ret = run_cmd(f'dfu-util -l') stdout = ret.stdout.decode() if f'serial="{uid}"' in stdout and 'Found DFU: [cafe:4000]' in stdout: break @@ -347,8 +347,7 @@ def test_device_dfu_runtime(board): # Wait device enum timeout = ENUM_TIMEOUT while timeout: - ret = subprocess.run(f'dfu-util -l', - shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + ret = run_cmd(f'dfu-util -l') stdout = ret.stdout.decode() if f'serial="{uid}"' in stdout and 'Found Runtime: [cafe:4000]' in stdout: break @@ -382,17 +381,18 @@ def test_device_hid_composite_freertos(id): # ------------------------------------------------------------- # Main # ------------------------------------------------------------- -# all possible tests: board_test is added last to disable board's usb -all_tests = [ +# device tests +device_tests = [ 'device/cdc_dual_ports', 'device/cdc_msc', 'device/dfu', 'device/cdc_msc_freertos', # don't test 2 cdc_msc next to each other 'device/dfu_runtime', 'device/hid_boot_interface', +] +dual_tests = [ 'dual/host_info_to_device_cdc', - 'device/board_test' ] @@ -401,17 +401,22 @@ def test_board(board): flasher = board['flasher'].lower() # default to all tests - test_list = list(all_tests) + test_list = list(device_tests) if 'tests' in board: board_tests = board['tests'] if 'only' in board_tests: - test_list = board_tests['only'] + ['device/board_test'] + test_list = board_tests['only'] if 'skip' in board_tests: for skip in board_tests['skip']: if skip in test_list: test_list.remove(skip) print(f'{name:25} {skip:30} ... Skip') + if 'dual_attached' in board_tests: + test_list += dual_tests + + # board_test is added last to disable board's usb + test_list.append('device/board_test') err_count = 0 for test in test_list: @@ -422,7 +427,7 @@ def test_board(board): print(f'{name:25} {test:30} ... ', end='') if not os.path.exists(fw_dir): - print('Skip') + print('Skip (no binary)') continue # flash firmware. It may fail randomly, retry a few times diff --git a/test/hil/requirements.txt b/test/hil/requirements.txt new file mode 100644 index 000000000..c33980c9d --- /dev/null +++ b/test/hil/requirements.txt @@ -0,0 +1,2 @@ +fs +pyfatfs diff --git a/test/hil/rpi.json b/test/hil/rpi.json deleted file mode 100644 index 672e857fd..000000000 --- a/test/hil/rpi.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "boards": [ - { - "name": "feather_nrf52840_express", - "uid": "1F0479CD0F764471", - "flasher": "jlink", - "flasher_sn": "000682804350", - "flasher_args": "-device nrf52840_xxaa" - }, - { - "name": "metro_m4_express", - "uid": "9995AD485337433231202020FF100A34", - "flasher": "jlink", - "flasher_sn": "123456", - "flasher_args": "-device ATSAMD51J19", - "tests": { - "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002130"}] - } - }, - { - "name": "max32666fthr", - "uid": "0C81464124010B20FF0A08CC2C", - "flasher": "openocd_adi", - "flasher_sn": "E6614C311B597D32", - "flasher_args": "-f interface/cmsis-dap.cfg -f target/max32665.cfg" - }, - { - "name": "lpcxpresso11u37", - "uid": "17121919", - "flasher": "jlink", - "flasher_sn": "000724441579", - "flasher_args": "-device LPC11U37/401" - }, - { - "name": "ra4m1_ek", - "uid": "152E163038303131393346E46F26574B", - "tests": { - "skip": ["device/cdc_msc", "device/cdc_msc_freertos"] - }, - "comment": "MSC is slow to enumerated #2602", - "flasher": "jlink", - "flasher_sn": "000831174392", - "flasher_args": "-device R7FA4M1AB" - }, - { - "name": "raspberry_pi_pico", - "uid": "E6614C311B764A37", - "flasher": "openocd", - "flasher_sn": "E6614103E72C1D2F", - "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"", - "tests": { - "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002470"}] - } - }, - { - "name": "raspberry_pi_pico2", - "uid": "560AE75E1C7152C9", - "flasher": "openocd", - "flasher_sn": "E6633861A3978538", - "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2350.cfg -c \"adapter speed 5000\"", - "tests": { - "skip": ["dual/host_info_to_device_cdc"], - "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "533D004242"}] - } - }, - { - "name": "stm32f072disco", - "uid": "3A001A001357364230353532", - "flasher": "jlink", - "flasher_sn": "779541626", - "flasher_args": "-device stm32f072rb" - }, - { - "name": "stm32g0b1nucleo", - "uid": "4D0038000450434E37343120", - "flasher": "openocd", - "flasher_sn": "066FFF495087534867063844", - "flasher_args": "-f interface/stlink.cfg -f target/stm32g0x.cfg" - } - ], - "boards-skip": [ - { - "name": "mimxrt1015_evk", - "uid": "DC28F865D2111D228D00B0543A70463C", - "flasher": "jlink", - "flasher_sn": "000726284213", - "flasher_args": "-device MIMXRT1015DAF5A" - }, - { - "name": "nanoch32v203", - "uid": "CDAB277B0FBC03E339E339E3", - "flasher": "openocd_wch", - "flasher_sn": "EBCA8F0670AF", - "flasher_args": "" - }, - { - "name": "espressif_s3_devkitm", - "uid": "84F703C084E4", - "tests": { - "only": ["device/cdc_msc_freertos", "device/hid_composite_freertos"] - }, - "flasher": "esptool", - "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", - "flasher_args": "-b 921600" - } - ] -} diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json new file mode 100644 index 000000000..fcd004c6d --- /dev/null +++ b/test/hil/tinyusb.json @@ -0,0 +1,107 @@ +{ + "boards": [ + { + "name": "feather_nrf52840_express", + "uid": "1F0479CD0F764471", + "flasher": "jlink", + "flasher_sn": "000682804350", + "flasher_args": "-device nrf52840_xxaa" + }, + { + "name": "metro_m4_express", + "uid": "9995AD485337433231202020FF100A34", + "flasher": "jlink", + "flasher_sn": "123456", + "flasher_args": "-device ATSAMD51J19", + "tests": { + "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002130"}] + } + }, + { + "name": "max32666fthr", + "uid": "0C81464124010B20FF0A08CC2C", + "flasher": "openocd_adi", + "flasher_sn": "E6614C311B597D32", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/max32665.cfg" + }, + { + "name": "lpcxpresso11u37", + "uid": "17121919", + "flasher": "jlink", + "flasher_sn": "000724441579", + "flasher_args": "-device LPC11U37/401" + }, + { + "name": "ra4m1_ek", + "uid": "152E163038303131393346E46F26574B", + "tests": { + "skip": ["device/cdc_msc", "device/cdc_msc_freertos"] + }, + "comment": "MSC is slow to enumerated #2602", + "flasher": "jlink", + "flasher_sn": "000831174392", + "flasher_args": "-device R7FA4M1AB" + }, + { + "name": "raspberry_pi_pico", + "uid": "E6614C311B764A37", + "flasher": "openocd", + "flasher_sn": "E6614103E72C1D2F", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"", + "tests": { + "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002470"}] + } + }, + { + "name": "raspberry_pi_pico2", + "uid": "560AE75E1C7152C9", + "flasher": "openocd", + "flasher_sn": "E6633861A3978538", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2350.cfg -c \"adapter speed 5000\"", + "tests": { + "skip": ["dual/host_info_to_device_cdc"], + "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "533D004242"}] + } + }, + { + "name": "stm32f072disco", + "uid": "3A001A001357364230353532", + "flasher": "jlink", + "flasher_sn": "779541626", + "flasher_args": "-device stm32f072rb" + }, + { + "name": "stm32g0b1nucleo", + "uid": "4D0038000450434E37343120", + "flasher": "openocd", + "flasher_sn": "066FFF495087534867063844", + "flasher_args": "-f interface/stlink.cfg -f target/stm32g0x.cfg" + }, + { + "name": "espressif_s3_devkitm", + "uid": "84F703C084E4", + "tests": { + "only": ["device/cdc_msc_freertos", "device/hid_composite_freertos"] + }, + "flasher": "esptool", + "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", + "flasher_args": "-b 921600" + } + ], + "boards-skip": [ + { + "name": "mimxrt1015_evk", + "uid": "DC28F865D2111D228D00B0543A70463C", + "flasher": "jlink", + "flasher_sn": "000726284213", + "flasher_args": "-device MIMXRT1015DAF5A" + }, + { + "name": "nanoch32v203", + "uid": "CDAB277B0FBC03E339E339E3", + "flasher": "openocd_wch", + "flasher_sn": "EBCA8F0670AF", + "flasher_args": "" + } + ] +} -- cgit v1.3.1 From 47233f863a5fa5255461514fada9af7771cf2146 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 18 Sep 2024 17:59:04 +0700 Subject: update to dwc2 register struct --- src/portable/synopsys/dwc2/dwc2_info.md | 110 +++++++++++++------------- src/portable/synopsys/dwc2/dwc2_info.py | 27 +++---- src/portable/synopsys/dwc2/dwc2_type.h | 136 +++++++++++++++++++++++++++----- test/hil/hil_test.py | 5 +- 4 files changed, 187 insertions(+), 91 deletions(-) diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index 8690a0755..a11b79671 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -1,55 +1,55 @@ -| | BCM2711 (Pi4) | EFM32GG FullSpeed | ESP32-S2 | STM32F407 Fullspeed | STM32F407 Highspeed | STM32F411 Fullspeed | STM32F412 Fullspeed | STM32F429 Fullspeed | STM32F429 Highspeed | STM32F723 Fullspeed | STM32F723 HighSpeed | STM32F767 Fullspeed | STM32H743 Highspeed | STM32L476 Fullspeed | STM32U5A5 Highspeed | GD32VF103 Fullspeed | XMC4500 | -|:----------------------------|:----------------|:--------------------|:-----------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:-----------| -| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00001200 | 0x00002000 | 0x00001200 | 0x00001100 | 0x00003000 | 0x00003100 | 0x00002000 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | -| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54281A | 0x4F54281A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | -| - specs version | 2.80a | 3.30a | 4.00a | 2.81a | 2.81a | 2.81a | 3.20a | 2.81a | 2.81a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | -| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | -| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x229DCD20 | 0x229ED590 | 0x229DCD20 | 0x229ED520 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229FE1D0 | 0x229ED520 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | -| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | -| - arch | 2 | 2 | 2 | 0 | 2 | 0 | 0 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | -| - point2point | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | -| - hs_phy_type | 1 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 2 | 0 | 3 | 0 | 2 | 0 | 1 | 0 | 0 | -| - fs_phy_type | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - num_dev_ep | 7 | 6 | 6 | 3 | 5 | 3 | 5 | 3 | 5 | 5 | 8 | 5 | 8 | 5 | 8 | 0 | 6 | -| - num_host_ch | 7 | 13 | 7 | 7 | 11 | 7 | 11 | 7 | 11 | 11 | 15 | 11 | 15 | 11 | 15 | 0 | 13 | -| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - nperiod_tx_q_depth | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - host_period_tx_q_depth | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - dev_token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | -| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x020001E8 | 0x03F403E8 | 0x020001E8 | 0x0200D1E8 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x03EED2E8 | 0x0200D1E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | -| - xfer_size_width | 8 | 8 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | -| - packet_size_width | 6 | 6 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | -| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - i2c_enable | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | -| - vendor_ctrl_itf | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | -| - optional_feature_removed | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | -| - total_fifo_size | 4080 | 498 | 200 | 512 | 1012 | 512 | 512 | 512 | 1012 | 512 | 1006 | 512 | 952 | 512 | 952 | 0 | 634 | -| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0x0FF08030 | 0x17F00030 | 0x0FF08030 | 0x17F08030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x23F00030 | 0x17F08030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | -| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - power_optimized | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - reserved7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 0 | 0 | -| - service_interval_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - ipg_isoc_en | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - acg_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - reserved13 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - utmi_phy_data_width | 0 | 2 | 2 | 2 | 0 | 2 | 2 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 0 | 2 | -| - dev_ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - iddg_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - vbus_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - a_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - b_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - num_dev_in_eps | 15 | 13 | 9 | 7 | 11 | 7 | 11 | 7 | 11 | 11 | 1 | 11 | 1 | 11 | 1 | 0 | 13 | -| - dma_desc_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | -| - dma_dynamic | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | STM32F 407/411/429 FS | STM32F407 HS | STM32F412 FS | STM32F429 HS | STM32F723 FS | STM32F723 HS | STM32F767 FS | STM32H743 HS | STM32L476 FS | STM32U5A5 HS | GD32VF103 FS | XMC4500 | +|:----------------------------|:----------------|:-------------|:--------------|:------------------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:-----------| +| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00001100 | 0x00003000 | 0x00003100 | 0x00002000 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | +| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54281A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | +| - specs version | 2.80a | 3.30a | 4.00a | 2.81a | 2.81a | 3.20a | 2.81a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | +| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED590 | 0x229ED520 | 0x229FE1D0 | 0x229ED520 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | +| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | +| - arch | 2 | 2 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | +| - point2point | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | +| - hs_phy_type | 1 | 0 | 0 | 0 | 2 | 0 | 2 | 0 | 3 | 0 | 2 | 0 | 1 | 0 | 0 | +| - fs_phy_type | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - num_dev_ep | 7 | 6 | 6 | 3 | 5 | 5 | 5 | 5 | 8 | 5 | 8 | 5 | 8 | 0 | 6 | +| - num_host_ch | 7 | 13 | 7 | 7 | 11 | 11 | 11 | 11 | 15 | 11 | 15 | 11 | 15 | 0 | 13 | +| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - nperiod_tx_q_depth | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - host_period_tx_q_depth | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - dev_token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | +| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x03F403E8 | 0x0200D1E8 | 0x03EED2E8 | 0x0200D1E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | +| - xfer_size_width | 8 | 8 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | +| - packet_size_width | 6 | 6 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | +| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - i2c_enable | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | +| - vendor_ctrl_itf | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | +| - optional_feature_removed | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | +| - total_fifo_size | 4080 | 498 | 200 | 512 | 1012 | 512 | 1012 | 512 | 1006 | 512 | 952 | 512 | 952 | 0 | 634 | +| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F00030 | 0x17F08030 | 0x23F00030 | 0x17F08030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | +| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - power_optimized | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - reserved7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 0 | 0 | +| - service_interval_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - ipg_isoc_en | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - acg_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - reserved13 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - utmi_phy_data_width | 0 | 2 | 2 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 0 | 2 | +| - dev_ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - iddg_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - vbus_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - a_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - b_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - num_dev_in_eps | 15 | 13 | 9 | 7 | 11 | 11 | 11 | 11 | 1 | 11 | 1 | 11 | 1 | 0 | 13 | +| - dma_desc_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | +| - dma_dynamic | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index 55bec3d23..6f3f195f0 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -3,24 +3,21 @@ import ctypes import pandas as pd # hex value for register: guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 +# Note: FS is FullSpeed, HS is HighSpeed dwc2_reg_list = ['guid', 'gsnpsid', 'ghwcfg1', 'ghwcfg2', 'ghwcfg3', 'ghwcfg4'] dwc2_reg_value = { 'BCM2711 (Pi4)': [0x2708A000, 0x4F54280A, 0, 0x228DDD50, 0xFF000E8, 0x1FF00020], - 'EFM32GG FullSpeed': [0, 0x4F54330A, 0, 0x228F5910, 0x1F204E8, 0x1BF08030], - 'ESP32-S2': [0, 0x4F54400A, 0, 0x224DD930, 0xC804B5, 0xD3F0A030], - 'STM32F407 Fullspeed': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], - 'STM32F407 Highspeed': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], - 'STM32F411 Fullspeed': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], - 'STM32F412 Fullspeed': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'STM32F429 Fullspeed': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], - 'STM32F429 Highspeed': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], - 'STM32F723 Fullspeed': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'STM32F723 HighSpeed': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x3EED2E8, 0x23F00030], - 'STM32F767 Fullspeed': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'STM32H743 Highspeed': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x3B8D2E8, 0xE3F00030], # both HS cores - 'STM32L476 Fullspeed': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'STM32U5A5 Highspeed': [0x00005000, 0x4F54411A, 0x00000000, 0x228FE052, 0x03B882E8, 0xE2103E30], - 'GD32VF103 Fullspeed': [0x1000, 0, 0, 0, 0, 0], + 'EFM32GG FS': [0, 0x4F54330A, 0, 0x228F5910, 0x1F204E8, 0x1BF08030], + 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0xC804B5, 0xD3F0A030], + 'STM32F 407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], + 'STM32F 407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], + 'STM32F 412/767 FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'STM32F723 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'STM32F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x3EED2E8, 0x23F00030], + 'STM32H743 HS': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x3B8D2E8, 0xE3F00030], # both HS cores + 'STM32L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'STM32U5A5 HS': [0x5000, 0x4F54411A, 0, 0x228FE052, 0x03B882E8, 0xE2103E30], + 'GD32VF103 FS': [0x1000, 0, 0, 0, 0, 0], 'XMC4500': [0xAEC000, 0x4F54292A, 0, 0x228F5930, 0x27A01E5, 0xDBF08030] } diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index c21bf9e94..97b9d1d8c 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -101,13 +101,15 @@ enum { }; enum { - GHWCFG2_ARCH_SLAVE_ONLY = 0, - GHWCFG2_ARCH_EXTERNAL_DMA, // 1 - GHWCFG2_ARCH_INTERNAL_DMA, // 2 + GHWCFG2_ARCH_SLAVE_ONLY = 0, + GHWCFG2_ARCH_EXTERNAL_DMA, // 1 + GHWCFG2_ARCH_INTERNAL_DMA, // 2 }; -typedef struct TU_ATTR_PACKED -{ +//-------------------------------------------------------------------- +// Register bitfield definitions +//-------------------------------------------------------------------- +typedef struct TU_ATTR_PACKED { uint32_t op_mode : 3; // 0: HNP and SRP | 1: SRP | 2: non-HNP, non-SRP uint32_t arch : 2; // 0: slave-only | 1: External DMA | 2: Internal DMA | 3: others uint32_t point2point : 1; // 0: support hub and split | 1: no hub, no split @@ -124,11 +126,9 @@ typedef struct TU_ATTR_PACKED uint32_t dev_token_q_depth : 5; // Device IN token sequence learning queue depth: 0-30 uint32_t otg_enable_ic_usb : 1; // IC_USB mode specified for mode of operation } dwc2_ghwcfg2_t; - TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg2_t) == 4, "incorrect size"); -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint32_t xfer_size_width : 4; // Transfer size counter in bits = 11 + n (max 19 bits) uint32_t packet_size_width : 3; // Packet size counter in bits = 4 + n (max 10 bits) uint32_t otg_enable : 1; // 1 is OTG capable @@ -142,11 +142,9 @@ typedef struct TU_ATTR_PACKED uint32_t lpm_mode : 1; // LPC mode uint32_t dfifo_depth : 16; // DFIFO depth - EP_LOC_CNT in terms of 32-bit words }dwc2_ghwcfg3_t; - TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg3_t) == 4, "incorrect size"); -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint32_t num_dev_period_in_ep : 4; // Number of Device Periodic IN Endpoints uint32_t power_optimized : 1; // Partial Power Down Enabled uint32_t ahb_freq_min : 1; // 1: minimum of AHB frequency is less than 60 MHz @@ -167,12 +165,110 @@ typedef struct TU_ATTR_PACKED uint32_t dma_desc_enable : 1; // scatter/gather DMA configuration uint32_t dma_dynamic : 1; // Dynamic scatter/gather DMA }dwc2_ghwcfg4_t; - TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg4_t) == 4, "incorrect size"); +typedef struct TU_ATTR_PACKED { + uint32_t ses_req_scs : 1; // 0: Session request success + uint32_t ses_req : 1; // 1: Session request + uint32_t vbval_ov_en : 1; // 2: VBUS valid override enable + uint32_t vbval_ov_val : 1; // 3: VBUS valid override value + uint32_t aval_ov_en : 1; // 4: A-peripheral session valid override enable + uint32_t aval_ov_al : 1; // 5: A-peripheral session valid override value + uint32_t bval_ov_en : 1; // 6: B-peripheral session valid override enable + uint32_t bval_ov_val : 1; // 7: B-peripheral session valid override value + uint32_t hng_scs : 1; // 8: Host negotiation success + uint32_t hnp_rq : 1; // 9: HNP (host negotiation protocol) request + uint32_t host_set_hnp_en : 1; // 10: Host set HNP enable + uint32_t dev_hnp_en : 1; // 11: Device HNP enabled + uint32_t embedded_host_en : 1; // 12: Embedded host enable + uint32_t rsv13_14 : 2; // 13..14: Reserved + uint32_t dbnc_filter_bypass : 1; // 15: Debounce filter bypass + uint32_t cid_status : 1; // 16: Connector ID status + uint32_t dbnc_done : 1; // 17: Debounce done + uint32_t ases_valid : 1; // 18: A-session valid + uint32_t bses_valid : 1; // 19: B-session valid + uint32_t otg_ver : 1; // 20: OTG version 0: v1.3, 1: v2.0 + uint32_t current_mode : 1; // 21: Current mode of operation 0: device, 1: host + uint32_t mult_val_id_bc : 5; // 22..26: Multi-valued input pin ID battery charger + uint32_t chirp_en : 1; // 27: Chirp detection enable + uint32_t rsv28_30 : 3; // 28..30: Reserved + uint32_t test_mode_corr_eusb2 : 1; // 31: Test mode control for eUSB2 PHY +} dwc2_gotgctl_t; +TU_VERIFY_STATIC(sizeof(dwc2_gotgctl_t) == 4, "incorrect size"); + +typedef struct TU_ATTR_PACKED { + uint32_t rsv0_1 : 2; // 0..1 : Reserved + uint32_t ses_end_det : 1; // 2 : Session end detected + uint32_t rsv3_7 : 5; // 3..7 : Reserved + uint32_t srs_status_change : 1; // 8 : Session request success status change + uint32_t hns_status_change : 1; // 9 : Host negotiation success status change + uint32_t rsv10_16 : 7; // 10..16 : Reserved + uint32_t hng_det : 1; // 17 : Host negotiation detected + uint32_t adev_timeout_change : 1; // 18 : A-device timeout change + uint32_t dbnc_done : 1; // 19 : Debounce done + uint32_t mult_val_lp_change : 1; // 20 : Multi-valued input pin change + uint32_t rsv21_31 :11; // 21..31 : Reserved +} dwc2_gotgint_t; +TU_VERIFY_STATIC(sizeof(dwc2_gotgint_t) == 4, "incorrect size"); + +typedef struct TU_ATTR_PACKED { + uint32_t gintmask : 1; // 0: Global interrupt mask + uint32_t hbst_len : 4; // 1..4: Burst length/type + uint32_t dma_en : 1; // 5: DMA enable + uint32_t rsv6 : 1; // 6: Reserved + uint32_t nptxf_empty_lvl : 1; // 7: Non-periodic Tx FIFO empty level + uint32_t ptxf_empty_lvl : 1; // 8: Periodic Tx FIFO empty level + uint32_t rsv9_20 : 12; // 9..20: Reserved + uint32_t remote_mem_support : 1; // 21: Remote memory support + uint32_t notify_all_dma_write : 1; // 22: Notify all DMA writes + uint32_t ahb_single : 1; // 23: AHB single + uint32_t inv_desc_endian : 1; // 24: Inverse descriptor endian + uint32_t rsv25_31 : 7; // 25..31: Reserved +} dwc2_gahbcfg_t; +TU_VERIFY_STATIC(sizeof(dwc2_gahbcfg_t) == 4, "incorrect size"); + +typedef struct TU_ATTR_PACKED { + uint32_t timeout_cal : 3; /* 0..2: Timeout calibration. + The USB standard timeout value for high-speed operation is 736 to 816 (inclusive) bit times. The USB standard + timeout value for full- speed operation is 16 to 18 (inclusive) bit times. The application must program this field + based on the speed of enumeration. The number of bit times added per PHY clock are as follows: + - High-speed: PHY clock One 30-MHz = 16 bit times, One 60-MHz = 8 bit times + - Full-speed: PHY clock One 30-MHz = 0.4 bit times, One 60-MHz = 0.2 bit times, One 48-MHz = 0.25 bit times */ + uint32_t phy_if : 1; // 3: PHY interface. 0: 8 bits, 1: 16 bits + uint32_t ulpi_utmi_sel : 1; // 4: ULPI/UTMI select. 0: UTMI+, 1: ULPI + uint32_t fs_intf_sel : 1; // 5: Fullspeed serial interface select. 0: 6-pin, 1: 3-pin + uint32_t phy_sel : 1; // 6: HS/FS PHY selection. 0: HS UTMI+ or ULPI, 1: FS serial transceiver + uint32_t ddr_sel : 1; // 7 ULPI DDR select. 0: Single data rate 8-bit, 1: Double data rate 4-bit + uint32_t srp_capable : 1; // 8: SRP-capable + uint32_t hnp_capable : 1; // 9: HNP-capable + uint32_t turnaround_time : 4; // 10..13 Turnaround time. 9: 8-bit UTMI+, 5: 16-bit UTMI+ + uint32_t rsv14 : 1; // 14: Reserved + uint32_t phy_low_power_clk_sel : 1; /* 15: PHY low-power clock select either 480-MHz or 48-MHz (low-power) PHY mode. + In FS/LS modes, the PHY can usually operate on a 48-MHz clock to save power. This bit is valid only for UTMI+ PHYs. + - 0: 480 Mhz internal PLL: the UTMI interface operates at either 60 MHz (8 bit) or 30 MHz (16-bit) + - 1 48 Mhz external clock: the UTMI interface operates at 48 MHz in FS mode and at either 48 or 6 MHz in LS mode */ + uint32_t otg_i2c_sel : 1; // 16: OTG I2C interface select. 0: UTMI-FS, 1: I2C for OTG signals + uint32_t ulpi_fsls : 1; /* 17: ULPI FS/LS select. 0: ULPI, 1: ULPI FS/LS. + valid only when the FS serial transceiver is selected on the ULPI PHY. */ + uint32_t ulpi_auto_resume : 1; // 18: ULPI Auto-resume + uint32_t ulpi_clk_sus_m : 1; // 19: ULPI Clock SuspendM + uint32_t ulpi_ext_vbus_drv : 1; // 20: ULPI External VBUS Drive + uint32_t ulpi_int_vbus_indicator : 1; // 21: ULPI Internal VBUS Indicator + uint32_t term_sel_dl_pulse : 1; // 22: TermSel DLine pulsing + uint32_t indicator_complement : 1; // 23: Indicator complement + uint32_t indicator_pass_through : 1; // 24: Indicator pass through + uint32_t ulpi_if_protect_disable : 1; // 25: ULPI interface protect disable + uint32_t ic_usb_capable : 1; // 26: IC_USB Capable + uint32_t ic_usb_traf_ctl : 1; // 27: IC_USB Traffic Control + uint32_t tx_end_delay : 1; // 28: TX end delay + uint32_t force_host_mode : 1; // 29: Force host mode + uint32_t force_dev_mode : 1; // 30: Force device mode + uint32_t corrupt_tx_pkt : 1; // 31: Corrupt Tx packet. 0: normal, 1: debug +} dwc2_gusbcfg_t; +TU_VERIFY_STATIC(sizeof(dwc2_gusbcfg_t) == 4, "incorrect size"); + // Host Channel -typedef struct -{ +typedef struct { volatile uint32_t hcchar; // 500 + 20*ch Host Channel Characteristics volatile uint32_t hcsplt; // 504 + 20*ch Host Channel Split Control volatile uint32_t hcint; // 508 + 20*ch Host Channel Interrupt @@ -184,8 +280,7 @@ typedef struct } dwc2_channel_t; // Endpoint IN -typedef struct -{ +typedef struct { volatile uint32_t diepctl; // 900 + 20*ep Device IN Endpoint Control uint32_t reserved04; // 904 volatile uint32_t diepint; // 908 + 20*ep Device IN Endpoint Interrupt @@ -197,8 +292,7 @@ typedef struct } dwc2_epin_t; // Endpoint OUT -typedef struct -{ +typedef struct { volatile uint32_t doepctl; // B00 + 20*ep Device OUT Endpoint Control uint32_t reserved04; // B04 volatile uint32_t doepint; // B08 + 20*ep Device OUT Endpoint Interrupt @@ -208,8 +302,10 @@ typedef struct uint32_t reserved18[2]; // B18..B1C } dwc2_epout_t; -typedef struct -{ +//-------------------------------------------------------------------- +// CSR Register Map +//-------------------------------------------------------------------- +typedef struct { //------------- Core Global -------------// volatile uint32_t gotgctl; // 000 OTG Control and Status volatile uint32_t gotgint; // 004 OTG Interrupt diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 2d14220c5..fc2e6c777 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -459,6 +459,8 @@ def main(): """ global verbose + duration = time.time() + parser = argparse.ArgumentParser() parser.add_argument('config_file', help='Configuration JSON file') parser.add_argument('-b', '--board', action='append', default=[], help='Boards to test, all if not specified') @@ -483,9 +485,10 @@ def main(): with Pool(processes=os.cpu_count()) as pool: err_count = sum(pool.map(test_board, config_boards)) + duration = time.time() - duration print() print("-" * 30) - print(f'Total failed: {err_count}') + print(f'Total failed: {err_count} in {duration:.1f}s') print("-" * 30) sys.exit(err_count) -- cgit v1.3.1 From bb2d1dd0c1bef04d495b05d609311e3b7ba870a7 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 24 Sep 2024 22:35:07 +0700 Subject: update/rename ghwcfg registers --- src/portable/synopsys/dwc2/dcd_dwc2.c | 21 +- src/portable/synopsys/dwc2/dwc2_info.md | 113 +++---- src/portable/synopsys/dwc2/dwc2_info.py | 37 +-- src/portable/synopsys/dwc2/dwc2_stm32.h | 6 +- src/portable/synopsys/dwc2/dwc2_type.h | 518 +++++++++++++++++--------------- 5 files changed, 366 insertions(+), 329 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index eb5b145e8..13143073d 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -538,13 +538,10 @@ static void reset_core(dwc2_regs_t* dwc2) { static bool phy_hs_supported(dwc2_regs_t* dwc2) { (void) dwc2; -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) - // note: esp32 incorrect report its hs_phy_type as utmi - return false; -#elif !TUD_OPT_HIGH_SPEED +#if !TUD_OPT_HIGH_SPEED return false; #else - return dwc2->ghwcfg2_bm.hs_phy_type != HS_PHY_TYPE_NONE; + return dwc2->ghwcfg2_bm.hs_phy_type != GHWCFG2_HSPHY_NOT_SUPPORTED; #endif } @@ -555,7 +552,7 @@ static void phy_fs_init(dwc2_regs_t* dwc2) { dwc2->gusbcfg |= GUSBCFG_PHYSEL; // MCU specific PHY init before reset - dwc2_phy_init(dwc2, HS_PHY_TYPE_NONE); + dwc2_phy_init(dwc2, GHWCFG2_HSPHY_NOT_SUPPORTED); // Reset core after selecting PHY reset_core(dwc2); @@ -566,7 +563,7 @@ static void phy_fs_init(dwc2_regs_t* dwc2) { dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (5u << GUSBCFG_TRDT_Pos); // MCU specific PHY update post reset - dwc2_phy_update(dwc2, HS_PHY_TYPE_NONE); + dwc2_phy_update(dwc2, GHWCFG2_HSPHY_NOT_SUPPORTED); // set max speed dwc2->dcfg = (dwc2->dcfg & ~DCFG_DSPD_Msk) | (DCFG_DSPD_FS << DCFG_DSPD_Pos); @@ -578,7 +575,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { // De-select FS PHY gusbcfg &= ~GUSBCFG_PHYSEL; - if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) { + if (dwc2->ghwcfg2_bm.hs_phy_type == GHWCFG2_HSPHY_ULPI) { TU_LOG(DWC2_DEBUG, "Highspeed ULPI PHY init\r\n"); // Select ULPI @@ -599,7 +596,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { gusbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16); // Set 16-bit interface if supported - if (dwc2->ghwcfg4_bm.utmi_phy_data_width) gusbcfg |= GUSBCFG_PHYIF16; + if (dwc2->ghwcfg4_bm.phy_data_width) gusbcfg |= GUSBCFG_PHYIF16; } // Apply config @@ -615,7 +612,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { // - 9 if using 8-bit PHY interface // - 5 if using 16-bit PHY interface gusbcfg &= ~GUSBCFG_TRDT_Msk; - gusbcfg |= (dwc2->ghwcfg4_bm.utmi_phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos; + gusbcfg |= (dwc2->ghwcfg4_bm.phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos; dwc2->gusbcfg = gusbcfg; // MCU specific PHY update post reset @@ -628,7 +625,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { // XCVRDLY: transceiver delay between xcvr_sel and txvalid during device chirp is required // when using with some PHYs such as USB334x (USB3341, USB3343, USB3346, USB3347) - if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) { + if (dwc2->ghwcfg2_bm.hs_phy_type == GHWCFG2_HSPHY_ULPI) { dcfg |= DCFG_XCVRDLY; } @@ -640,7 +637,7 @@ static bool check_dwc2(dwc2_regs_t* dwc2) { print_dwc2_info(dwc2); #endif - // For some reasons: GD32VF103 snpsid and all hwcfg register are always zero (skip it) + // For some reason: GD32VF103 snpsid and all hwcfg register are always zero (skip it) (void) dwc2; #if !TU_CHECK_MCU(OPT_MCU_GD32VF103) uint32_t const gsnpsid = dwc2->gsnpsid & GSNPSID_ID_MASK; diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index a11b79671..9798fb0de 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -1,55 +1,58 @@ -| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | STM32F 407/411/429 FS | STM32F407 HS | STM32F412 FS | STM32F429 HS | STM32F723 FS | STM32F723 HS | STM32F767 FS | STM32H743 HS | STM32L476 FS | STM32U5A5 HS | GD32VF103 FS | XMC4500 | -|:----------------------------|:----------------|:-------------|:--------------|:------------------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:-----------| -| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00001100 | 0x00003000 | 0x00003100 | 0x00002000 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | -| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54281A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | -| - specs version | 2.80a | 3.30a | 4.00a | 2.81a | 2.81a | 3.20a | 2.81a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | -| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | -| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED590 | 0x229ED520 | 0x229FE1D0 | 0x229ED520 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | -| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | -| - arch | 2 | 2 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | -| - point2point | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | -| - hs_phy_type | 1 | 0 | 0 | 0 | 2 | 0 | 2 | 0 | 3 | 0 | 2 | 0 | 1 | 0 | 0 | -| - fs_phy_type | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - num_dev_ep | 7 | 6 | 6 | 3 | 5 | 5 | 5 | 5 | 8 | 5 | 8 | 5 | 8 | 0 | 6 | -| - num_host_ch | 7 | 13 | 7 | 7 | 11 | 11 | 11 | 11 | 15 | 11 | 15 | 11 | 15 | 0 | 13 | -| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - nperiod_tx_q_depth | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - host_period_tx_q_depth | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - dev_token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | -| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x03F403E8 | 0x0200D1E8 | 0x03EED2E8 | 0x0200D1E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | -| - xfer_size_width | 8 | 8 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | -| - packet_size_width | 6 | 6 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | -| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - i2c_enable | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | -| - vendor_ctrl_itf | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | -| - optional_feature_removed | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | -| - total_fifo_size | 4080 | 498 | 200 | 512 | 1012 | 512 | 1012 | 512 | 1006 | 512 | 952 | 512 | 952 | 0 | 634 | -| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F00030 | 0x17F08030 | 0x23F00030 | 0x17F08030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | -| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - power_optimized | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - reserved7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 0 | 0 | -| - service_interval_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - ipg_isoc_en | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - acg_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - reserved13 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - utmi_phy_data_width | 0 | 2 | 2 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 0 | 2 | -| - dev_ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - iddg_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - vbus_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - a_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - b_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - num_dev_in_eps | 15 | 13 | 9 | 7 | 11 | 11 | 11 | 11 | 1 | 11 | 1 | 11 | 1 | 0 | 13 | -| - dma_desc_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | -| - dma_dynamic | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | STM32F 407/411/429 FS | STM32F 407/429 HS | STM32F 412/767 FS | STM32F723 FS | STM32F723 HS | STM32H743 HS | STM32L476 FS | STM32U5A5 HS | GD32VF103 FS | XMC4500 | +|:---------------------------|:----------------|:-------------|:--------------|:------------------------|:--------------------|:--------------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:-----------| +| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | +| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | +| - specs version | 2.80a | 3.30a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | +| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | +| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | +| - arch | 2 | 2 | 2 | 0 | 2 | 0 | 0 | 2 | 2 | 0 | 2 | 0 | 2 | +| - point2point | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | +| - hs_phy_type | 1 | 0 | 0 | 0 | 2 | 0 | 0 | 3 | 2 | 0 | 1 | 0 | 0 | +| - fs_phy_type | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - num_dev_ep | 7 | 6 | 6 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | +| - num_host_ch | 7 | 13 | 7 | 7 | 11 | 11 | 11 | 15 | 15 | 11 | 15 | 0 | 13 | +| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - nptx_q_depth | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - ptx_q_depth | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | +| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | +| - xfer_size_width | 8 | 8 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | +| - packet_size_width | 6 | 6 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | +| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - i2c_enable | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | +| - vendor_ctrl_itf | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | +| - optional_feature_removed | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | +| - dfifo_depth | 4080 | 498 | 200 | 512 | 1012 | 512 | 512 | 1006 | 952 | 512 | 952 | 0 | 634 | +| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | +| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - enhanced_lpm_support | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - phy_data_width | 0 | 2 | 2 | 2 | 0 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 2 | +| - ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - num_dev_in_eps | 7 | 6 | 4 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | +| - dma_desc_enable | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| - dma_desc_dynamic | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index 6f3f195f0..871ac112d 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -47,9 +47,9 @@ class GHWCFG2(ctypes.LittleEndianStructure): ("enable_dynamic_fifo", ctypes.c_uint32, 1), ("mul_cpu_int", ctypes.c_uint32, 1), ("reserved21", ctypes.c_uint32, 1), - ("nperiod_tx_q_depth", ctypes.c_uint32, 2), - ("host_period_tx_q_depth", ctypes.c_uint32, 2), - ("dev_token_q_depth", ctypes.c_uint32, 5), + ("nptx_q_depth", ctypes.c_uint32, 2), + ("ptx_q_depth", ctypes.c_uint32, 2), + ("token_q_depth", ctypes.c_uint32, 5), ("otg_enable_ic_usb", ctypes.c_uint32, 1) ] @@ -67,31 +67,34 @@ class GHWCFG3(ctypes.LittleEndianStructure): ("otg_enable_hsic", ctypes.c_uint32, 1), ("battery_charger_support", ctypes.c_uint32, 1), ("lpm_mode", ctypes.c_uint32, 1), - ("total_fifo_size", ctypes.c_uint32, 16) + ("dfifo_depth", ctypes.c_uint32, 16) ] class GHWCFG4(ctypes.LittleEndianStructure): _fields_ = [ ("num_dev_period_in_ep", ctypes.c_uint32, 4), - ("power_optimized", ctypes.c_uint32, 1), + ("partial_powerdown", ctypes.c_uint32, 1), ("ahb_freq_min", ctypes.c_uint32, 1), ("hibernation", ctypes.c_uint32, 1), - ("reserved7", ctypes.c_uint32, 3), - ("service_interval_mode", ctypes.c_uint32, 1), - ("ipg_isoc_en", ctypes.c_uint32, 1), - ("acg_enable", ctypes.c_uint32, 1), - ("reserved13", ctypes.c_uint32, 1), - ("utmi_phy_data_width", ctypes.c_uint32, 2), - ("dev_ctrl_ep_num", ctypes.c_uint32, 4), - ("iddg_filter_enabled", ctypes.c_uint32, 1), - ("vbus_valid_filter_enabled", ctypes.c_uint32, 1), - ("a_valid_filter_enabled", ctypes.c_uint32, 1), - ("b_valid_filter_enabled", ctypes.c_uint32, 1), + ("extended_hibernation", ctypes.c_uint32, 1), + ("reserved8", ctypes.c_uint32, 1), + ("enhanced_lpm_support1", ctypes.c_uint32, 1), + ("service_interval_flow", ctypes.c_uint32, 1), + ("ipg_isoc_support", ctypes.c_uint32, 1), + ("acg_support", ctypes.c_uint32, 1), + ("enhanced_lpm_support", ctypes.c_uint32, 1), + ("phy_data_width", ctypes.c_uint32, 2), + ("ctrl_ep_num", ctypes.c_uint32, 4), + ("iddg_filter", ctypes.c_uint32, 1), + ("vbus_valid_filter", ctypes.c_uint32, 1), + ("a_valid_filter", ctypes.c_uint32, 1), + ("b_valid_filter", ctypes.c_uint32, 1), + ("session_end_filter", ctypes.c_uint32, 1), ("dedicated_fifos", ctypes.c_uint32, 1), ("num_dev_in_eps", ctypes.c_uint32, 4), ("dma_desc_enable", ctypes.c_uint32, 1), - ("dma_dynamic", ctypes.c_uint32, 1) + ("dma_desc_dynamic", ctypes.c_uint32, 1) ] diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 3237a50f6..395b6d870 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -142,7 +142,7 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) { // - dwc2 3.30a (H5) use USB_HS_PHYC // - dwc2 4.11a (U5) use femtoPHY static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { - if (hs_phy_type == HS_PHY_TYPE_NONE) { + if (hs_phy_type == GHWCFG2_HSPHY_NOT_SUPPORTED) { // Enable on-chip FS PHY dwc2->stm32_gccfg |= STM32_GCCFG_PWRDWN; @@ -175,7 +175,7 @@ static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { #endif // Enable on-chip HS PHY - if (hs_phy_type == HS_PHY_TYPE_UTMI || hs_phy_type == HS_PHY_TYPE_UTMI_ULPI) { + if (hs_phy_type == GHWCFG2_HSPHY_UTMI || hs_phy_type == GHWCFG2_HSPHY_UTMI_ULPI) { #ifdef USB_HS_PHYC // Enable UTMI HS PHY dwc2->stm32_gccfg |= STM32_GCCFG_PHYHSEN; @@ -218,7 +218,7 @@ static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { // used to set turnaround time for fullspeed, nothing to do in highspeed mode - if (hs_phy_type == HS_PHY_TYPE_NONE) { + if (hs_phy_type == GHWCFG2_HSPHY_NOT_SUPPORTED) { // Turnaround timeout depends on the AHB clock dictated by STM32 Reference Manual uint32_t turnaround; diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index 97b9d1d8c..ac88dd24d 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -87,186 +87,220 @@ typedef struct #endif enum { - HS_PHY_TYPE_NONE = 0 , // not supported - HS_PHY_TYPE_UTMI , // internal PHY (mostly) - HS_PHY_TYPE_ULPI , // external PHY - HS_PHY_TYPE_UTMI_ULPI , + GHWCFG2_OPMODE_HNP_SRP = 0, + GHWCFG2_OPMODE_SRP = 1, + GHWCFG2_OPMODE_NON_HNP_NON_SRP = 2, + GHWCFG2_OPMODE_SRP_DEVICE = 3, + GHWCFFG2_OPMODE_NON_OTG_DEVICE = 4, + GHWCFG2_OPMODE_SRP_HOST = 5, + GHWCFG2_OPMODE_NON_OTG_HOST = 6, +}; +enum { + GHWCFG2_ARCH_SLAVE_ONLY = 0, + GHWCFG2_ARCH_EXTERNAL_DMA = 1, + GHWCFG2_ARCH_INTERNAL_DMA = 2, +}; + +enum { + GHWCFG2_HSPHY_NOT_SUPPORTED = 0, + GHWCFG2_HSPHY_UTMI = 1, // internal PHY (mostly) + GHWCFG2_HSPHY_ULPI = 2, // external PHY (mostly) + GHWCFG2_HSPHY_UTMI_ULPI = 3, // both + }; enum { - FS_PHY_TYPE_NONE = 0, // not supported - FS_PHY_TYPE_DEDICATED, - FS_PHY_TYPE_UTMI, - FS_PHY_TYPE_ULPI, + GHWCFG2_FSPHY_NOT_SUPPORTED = 0, + GHWCFG2_FSPHY_DEDICATED = 1, // have dedicated FS PHY + GHWCFG2_FSPHY_UTMI = 2, // shared with UTMI+ + GHWCFG2_FSPHY_ULPI = 3, // shared with ULPI }; enum { - GHWCFG2_ARCH_SLAVE_ONLY = 0, - GHWCFG2_ARCH_EXTERNAL_DMA, // 1 - GHWCFG2_ARCH_INTERNAL_DMA, // 2 + GHWCFFG4_PHY_DATA_WIDTH_8 = 0, + GHWCFFG4_PHY_DATA_WIDTH_16 = 1, + GHWCFFG4_PHY_DATA_WIDTH_8_16 = 2, // software selectable }; //-------------------------------------------------------------------- // Register bitfield definitions //-------------------------------------------------------------------- typedef struct TU_ATTR_PACKED { - uint32_t op_mode : 3; // 0: HNP and SRP | 1: SRP | 2: non-HNP, non-SRP - uint32_t arch : 2; // 0: slave-only | 1: External DMA | 2: Internal DMA | 3: others - uint32_t point2point : 1; // 0: support hub and split | 1: no hub, no split - uint32_t hs_phy_type : 2; // 0: not supported | 1: UTMI+ | 2: ULPI | 3: UTMI+ and ULPI - uint32_t fs_phy_type : 2; // 0: not supported | 1: dedicated | 2: UTMI+ | 3: ULPI - uint32_t num_dev_ep : 4; // Number of device endpoints (not including EP0) - uint32_t num_host_ch : 4; // Number of host channel - uint32_t period_channel_support : 1; // Support Periodic OUT Host Channel - uint32_t enable_dynamic_fifo : 1; // Dynamic FIFO Sizing Enabled - uint32_t mul_cpu_int : 1; // Multi-Processor Interrupt Enabled - uint32_t reserved21 : 1; - uint32_t nperiod_tx_q_depth : 2; // Non-periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 - uint32_t host_period_tx_q_depth : 2; // Host periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 - uint32_t dev_token_q_depth : 5; // Device IN token sequence learning queue depth: 0-30 - uint32_t otg_enable_ic_usb : 1; // IC_USB mode specified for mode of operation -} dwc2_ghwcfg2_t; -TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg2_t) == 4, "incorrect size"); - -typedef struct TU_ATTR_PACKED { - uint32_t xfer_size_width : 4; // Transfer size counter in bits = 11 + n (max 19 bits) - uint32_t packet_size_width : 3; // Packet size counter in bits = 4 + n (max 10 bits) - uint32_t otg_enable : 1; // 1 is OTG capable - uint32_t i2c_enable : 1; // I2C interface is available - uint32_t vendor_ctrl_itf : 1; // Vendor control interface is available - uint32_t optional_feature_removed : 1; // remove User ID, GPIO, SOF toggle & counter - uint32_t synch_reset : 1; // 0: async reset | 1: synch reset - uint32_t otg_adp_support : 1; // ADP logic is present along with HSOTG controller - uint32_t otg_enable_hsic : 1; // 1: HSIC-capable with shared UTMI PHY interface | 0: non-HSIC - uint32_t battery_charger_support : 1; // support battery charger - uint32_t lpm_mode : 1; // LPC mode - uint32_t dfifo_depth : 16; // DFIFO depth - EP_LOC_CNT in terms of 32-bit words -}dwc2_ghwcfg3_t; -TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg3_t) == 4, "incorrect size"); - -typedef struct TU_ATTR_PACKED { - uint32_t num_dev_period_in_ep : 4; // Number of Device Periodic IN Endpoints - uint32_t power_optimized : 1; // Partial Power Down Enabled - uint32_t ahb_freq_min : 1; // 1: minimum of AHB frequency is less than 60 MHz - uint32_t hibernation : 1; // Hibernation feature is enabled - uint32_t reserved7 : 3; - uint32_t service_interval_mode : 1; // Service Interval supported - uint32_t ipg_isoc_en : 1; // IPG ISOC supported - uint32_t acg_enable : 1; // ACG enabled - uint32_t reserved13 : 1; - uint32_t utmi_phy_data_width : 2; // 0: 8 bits | 1: 16 bits | 2: 8/16 software selectable - uint32_t dev_ctrl_ep_num : 4; // Number of Device control endpoints in addition to EP0 - uint32_t iddg_filter_enabled : 1; - uint32_t vbus_valid_filter_enabled : 1; - uint32_t a_valid_filter_enabled : 1; - uint32_t b_valid_filter_enabled : 1; - uint32_t dedicated_fifos : 1; // Dedicated tx fifo for device IN Endpoint is enabled - uint32_t num_dev_in_eps : 4; // Number of Device IN Endpoints including EP0 - uint32_t dma_desc_enable : 1; // scatter/gather DMA configuration - uint32_t dma_dynamic : 1; // Dynamic scatter/gather DMA -}dwc2_ghwcfg4_t; -TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg4_t) == 4, "incorrect size"); - -typedef struct TU_ATTR_PACKED { - uint32_t ses_req_scs : 1; // 0: Session request success - uint32_t ses_req : 1; // 1: Session request - uint32_t vbval_ov_en : 1; // 2: VBUS valid override enable - uint32_t vbval_ov_val : 1; // 3: VBUS valid override value - uint32_t aval_ov_en : 1; // 4: A-peripheral session valid override enable - uint32_t aval_ov_al : 1; // 5: A-peripheral session valid override value - uint32_t bval_ov_en : 1; // 6: B-peripheral session valid override enable - uint32_t bval_ov_val : 1; // 7: B-peripheral session valid override value - uint32_t hng_scs : 1; // 8: Host negotiation success - uint32_t hnp_rq : 1; // 9: HNP (host negotiation protocol) request - uint32_t host_set_hnp_en : 1; // 10: Host set HNP enable - uint32_t dev_hnp_en : 1; // 11: Device HNP enabled - uint32_t embedded_host_en : 1; // 12: Embedded host enable - uint32_t rsv13_14 : 2; // 13..14: Reserved - uint32_t dbnc_filter_bypass : 1; // 15: Debounce filter bypass - uint32_t cid_status : 1; // 16: Connector ID status - uint32_t dbnc_done : 1; // 17: Debounce done - uint32_t ases_valid : 1; // 18: A-session valid - uint32_t bses_valid : 1; // 19: B-session valid - uint32_t otg_ver : 1; // 20: OTG version 0: v1.3, 1: v2.0 - uint32_t current_mode : 1; // 21: Current mode of operation 0: device, 1: host - uint32_t mult_val_id_bc : 5; // 22..26: Multi-valued input pin ID battery charger - uint32_t chirp_en : 1; // 27: Chirp detection enable - uint32_t rsv28_30 : 3; // 28..30: Reserved - uint32_t test_mode_corr_eusb2 : 1; // 31: Test mode control for eUSB2 PHY + uint32_t ses_req_scs : 1; // 0 Session request success + uint32_t ses_req : 1; // 1 Session request + uint32_t vbval_ov_en : 1; // 2 VBUS valid override enable + uint32_t vbval_ov_val : 1; // 3 VBUS valid override value + uint32_t aval_ov_en : 1; // 4 A-peripheral session valid override enable + uint32_t aval_ov_al : 1; // 5 A-peripheral session valid override value + uint32_t bval_ov_en : 1; // 6 B-peripheral session valid override enable + uint32_t bval_ov_val : 1; // 7 B-peripheral session valid override value + uint32_t hng_scs : 1; // 8 Host negotiation success + uint32_t hnp_rq : 1; // 9 HNP (host negotiation protocol) request + uint32_t host_set_hnp_en : 1; // 10 Host set HNP enable + uint32_t dev_hnp_en : 1; // 11 Device HNP enabled + uint32_t embedded_host_en : 1; // 12 Embedded host enable + uint32_t rsv13_14 : 2; // 13.14 Reserved + uint32_t dbnc_filter_bypass : 1; // 15 Debounce filter bypass + uint32_t cid_status : 1; // 16 Connector ID status + uint32_t dbnc_done : 1; // 17 Debounce done + uint32_t ases_valid : 1; // 18 A-session valid + uint32_t bses_valid : 1; // 19 B-session valid + uint32_t otg_ver : 1; // 20 OTG version 0: v1.3, 1: v2.0 + uint32_t current_mode : 1; // 21 Current mode of operation 0: device, 1: host + uint32_t mult_val_id_bc : 5; // 22..26 Multi-valued input pin ID battery charger + uint32_t chirp_en : 1; // 27 Chirp detection enable + uint32_t rsv28_30 : 3; // 28.30: Reserved + uint32_t test_mode_corr_eusb2 : 1; // 31 Test mode control for eUSB2 PHY } dwc2_gotgctl_t; TU_VERIFY_STATIC(sizeof(dwc2_gotgctl_t) == 4, "incorrect size"); typedef struct TU_ATTR_PACKED { - uint32_t rsv0_1 : 2; // 0..1 : Reserved - uint32_t ses_end_det : 1; // 2 : Session end detected - uint32_t rsv3_7 : 5; // 3..7 : Reserved - uint32_t srs_status_change : 1; // 8 : Session request success status change - uint32_t hns_status_change : 1; // 9 : Host negotiation success status change - uint32_t rsv10_16 : 7; // 10..16 : Reserved - uint32_t hng_det : 1; // 17 : Host negotiation detected - uint32_t adev_timeout_change : 1; // 18 : A-device timeout change - uint32_t dbnc_done : 1; // 19 : Debounce done - uint32_t mult_val_lp_change : 1; // 20 : Multi-valued input pin change - uint32_t rsv21_31 :11; // 21..31 : Reserved + uint32_t rsv0_1 : 2; // 0..1 Reserved + uint32_t ses_end_det : 1; // 2 Session end detected + uint32_t rsv3_7 : 5; // 3..7 Reserved + uint32_t srs_status_change : 1; // 8 Session request success status change + uint32_t hns_status_change : 1; // 9 Host negotiation success status change + uint32_t rsv10_16 : 7; // 10..16 Reserved + uint32_t hng_det : 1; // 17 Host negotiation detected + uint32_t adev_timeout_change : 1; // 18 A-device timeout change + uint32_t dbnc_done : 1; // 19 Debounce done + uint32_t mult_val_lp_change : 1; // 20 Multi-valued input pin change + uint32_t rsv21_31 :11; // 21..31 Reserved } dwc2_gotgint_t; TU_VERIFY_STATIC(sizeof(dwc2_gotgint_t) == 4, "incorrect size"); typedef struct TU_ATTR_PACKED { - uint32_t gintmask : 1; // 0: Global interrupt mask - uint32_t hbst_len : 4; // 1..4: Burst length/type - uint32_t dma_en : 1; // 5: DMA enable - uint32_t rsv6 : 1; // 6: Reserved - uint32_t nptxf_empty_lvl : 1; // 7: Non-periodic Tx FIFO empty level - uint32_t ptxf_empty_lvl : 1; // 8: Periodic Tx FIFO empty level - uint32_t rsv9_20 : 12; // 9..20: Reserved - uint32_t remote_mem_support : 1; // 21: Remote memory support - uint32_t notify_all_dma_write : 1; // 22: Notify all DMA writes - uint32_t ahb_single : 1; // 23: AHB single - uint32_t inv_desc_endian : 1; // 24: Inverse descriptor endian - uint32_t rsv25_31 : 7; // 25..31: Reserved + uint32_t gintmask : 1; // 0 Global interrupt mask + uint32_t hbst_len : 4; // 1..4 Burst length/type + uint32_t dma_en : 1; // 5 DMA enable + uint32_t rsv6 : 1; // 6 Reserved + uint32_t nptxf_empty_lvl : 1; // 7 Non-periodic Tx FIFO empty level + uint32_t ptxf_empty_lvl : 1; // 8 Periodic Tx FIFO empty level + uint32_t rsv9_20 : 12; // 9.20: Reserved + uint32_t remote_mem_support : 1; // 21 Remote memory support + uint32_t notify_all_dma_write : 1; // 22 Notify all DMA writes + uint32_t ahb_single : 1; // 23 AHB single + uint32_t inv_desc_endian : 1; // 24 Inverse descriptor endian + uint32_t rsv25_31 : 7; // 25..31 Reserved } dwc2_gahbcfg_t; TU_VERIFY_STATIC(sizeof(dwc2_gahbcfg_t) == 4, "incorrect size"); typedef struct TU_ATTR_PACKED { - uint32_t timeout_cal : 3; /* 0..2: Timeout calibration. + uint32_t timeout_cal : 3; /* 0..2 Timeout calibration. The USB standard timeout value for high-speed operation is 736 to 816 (inclusive) bit times. The USB standard timeout value for full- speed operation is 16 to 18 (inclusive) bit times. The application must program this field based on the speed of enumeration. The number of bit times added per PHY clock are as follows: - High-speed: PHY clock One 30-MHz = 16 bit times, One 60-MHz = 8 bit times - Full-speed: PHY clock One 30-MHz = 0.4 bit times, One 60-MHz = 0.2 bit times, One 48-MHz = 0.25 bit times */ - uint32_t phy_if : 1; // 3: PHY interface. 0: 8 bits, 1: 16 bits - uint32_t ulpi_utmi_sel : 1; // 4: ULPI/UTMI select. 0: UTMI+, 1: ULPI - uint32_t fs_intf_sel : 1; // 5: Fullspeed serial interface select. 0: 6-pin, 1: 3-pin - uint32_t phy_sel : 1; // 6: HS/FS PHY selection. 0: HS UTMI+ or ULPI, 1: FS serial transceiver - uint32_t ddr_sel : 1; // 7 ULPI DDR select. 0: Single data rate 8-bit, 1: Double data rate 4-bit - uint32_t srp_capable : 1; // 8: SRP-capable - uint32_t hnp_capable : 1; // 9: HNP-capable - uint32_t turnaround_time : 4; // 10..13 Turnaround time. 9: 8-bit UTMI+, 5: 16-bit UTMI+ - uint32_t rsv14 : 1; // 14: Reserved - uint32_t phy_low_power_clk_sel : 1; /* 15: PHY low-power clock select either 480-MHz or 48-MHz (low-power) PHY mode. + uint32_t phy_if : 1; // 3 PHY interface. 0: 8 bits, 1: 16 bits + uint32_t ulpi_utmi_sel : 1; // 4 ULPI/UTMI select. 0: UTMI+, 1: ULPI + uint32_t fs_intf_sel : 1; // 5 Fullspeed serial interface select. 0: 6-pin, 1: 3-pin + uint32_t phy_sel : 1; // 6 HS/FS PHY selection. 0: HS UTMI+ or ULPI, 1: FS serial transceiver + uint32_t ddr_sel : 1; // 7 ULPI DDR select. 0: Single data rate 8-bit, 1: Double data rate 4-bit + uint32_t srp_capable : 1; // 8 SRP-capable + uint32_t hnp_capable : 1; // 9 HNP-capable + uint32_t turnaround_time : 4; // 10..13 Turnaround time. 9: 8-bit UTMI+, 5: 16-bit UTMI+ + uint32_t rsv14 : 1; // 14 Reserved + uint32_t phy_low_power_clk_sel : 1; /* 15 PHY low-power clock select either 480-MHz or 48-MHz (low-power) PHY mode. In FS/LS modes, the PHY can usually operate on a 48-MHz clock to save power. This bit is valid only for UTMI+ PHYs. - 0: 480 Mhz internal PLL: the UTMI interface operates at either 60 MHz (8 bit) or 30 MHz (16-bit) - 1 48 Mhz external clock: the UTMI interface operates at 48 MHz in FS mode and at either 48 or 6 MHz in LS mode */ - uint32_t otg_i2c_sel : 1; // 16: OTG I2C interface select. 0: UTMI-FS, 1: I2C for OTG signals - uint32_t ulpi_fsls : 1; /* 17: ULPI FS/LS select. 0: ULPI, 1: ULPI FS/LS. - valid only when the FS serial transceiver is selected on the ULPI PHY. */ - uint32_t ulpi_auto_resume : 1; // 18: ULPI Auto-resume - uint32_t ulpi_clk_sus_m : 1; // 19: ULPI Clock SuspendM - uint32_t ulpi_ext_vbus_drv : 1; // 20: ULPI External VBUS Drive - uint32_t ulpi_int_vbus_indicator : 1; // 21: ULPI Internal VBUS Indicator - uint32_t term_sel_dl_pulse : 1; // 22: TermSel DLine pulsing - uint32_t indicator_complement : 1; // 23: Indicator complement - uint32_t indicator_pass_through : 1; // 24: Indicator pass through - uint32_t ulpi_if_protect_disable : 1; // 25: ULPI interface protect disable - uint32_t ic_usb_capable : 1; // 26: IC_USB Capable - uint32_t ic_usb_traf_ctl : 1; // 27: IC_USB Traffic Control - uint32_t tx_end_delay : 1; // 28: TX end delay - uint32_t force_host_mode : 1; // 29: Force host mode - uint32_t force_dev_mode : 1; // 30: Force device mode - uint32_t corrupt_tx_pkt : 1; // 31: Corrupt Tx packet. 0: normal, 1: debug + uint32_t otg_i2c_sel : 1; // 16 OTG I2C interface select. 0: UTMI-FS, 1: I2C for OTG signals + uint32_t ulpi_fsls : 1; /* 17 ULPI FS/LS select. 0: ULPI, 1: ULPI FS/LS. + valid only when the FS serial transceiver is selected on the ULPI PHY. */ + uint32_t ulpi_auto_resume : 1; // 18 ULPI Auto-resume + uint32_t ulpi_clk_sus_m : 1; // 19 ULPI Clock SuspendM + uint32_t ulpi_ext_vbus_drv : 1; // 20 ULPI External VBUS Drive + uint32_t ulpi_int_vbus_indicator : 1; // 21 ULPI Internal VBUS Indicator + uint32_t term_sel_dl_pulse : 1; // 22 TermSel DLine pulsing + uint32_t indicator_complement : 1; // 23 Indicator complement + uint32_t indicator_pass_through : 1; // 24 Indicator pass through + uint32_t ulpi_if_protect_disable : 1; // 25 ULPI interface protect disable + uint32_t ic_usb_capable : 1; // 26 IC_USB Capable + uint32_t ic_usb_traf_ctl : 1; // 27 IC_USB Traffic Control + uint32_t tx_end_delay : 1; // 28 TX end delay + uint32_t force_host_mode : 1; // 29 Force host mode + uint32_t force_dev_mode : 1; // 30 Force device mode + uint32_t corrupt_tx_pkt : 1; // 31 Corrupt Tx packet. 0: normal, 1: debug } dwc2_gusbcfg_t; TU_VERIFY_STATIC(sizeof(dwc2_gusbcfg_t) == 4, "incorrect size"); +typedef struct TU_ATTR_PACKED { + uint32_t core_soft_rst : 1; // 0 Core Soft Reset + uint32_t piufs_soft_rst : 1; // 1 PIU FS Dedicated Controller Soft Reset + uint32_t frame_counter_rst : 1; // 2 Frame Counter Reset (host) + uint32_t intoken_q_flush : 1; // 3 IN Token Queue Flush + uint32_t rx_fifo_flush : 1; // 4 RX FIFO Flush + uint32_t tx_fifo_flush : 1; // 5 TX FIFO Flush + uint32_t tx_fifo_num : 5; // 6..10 TX FIFO Number + uint32_t rsv11_28 :18; // 11..28 Reserved + uint32_t core_soft_rst_done : 1; // 29 Core Soft Reset Done, from v4.20a + uint32_t dma_req : 1; // 30 DMA Request + uint32_t ahb_idle : 1; // 31 AHB Idle +} dwc2_grstctl_t; +TU_VERIFY_STATIC(sizeof(dwc2_grstctl_t) == 4, "incorrect size"); + +typedef struct TU_ATTR_PACKED { + uint32_t op_mode : 3; // 0..2 HNP/SRP Host/Device/OTG mode + uint32_t arch : 2; // 3..4 Slave/External/Internal DMA + uint32_t point2point : 1; // 5 0: support hub and split | 1: no hub, no split + uint32_t hs_phy_type : 2; // 6..7 0: not supported | 1: UTMI+ | 2: ULPI | 3: UTMI+ and ULPI + uint32_t fs_phy_type : 2; // 8..9 0: not supported | 1: dedicated | 2: UTMI+ | 3: ULPI + uint32_t num_dev_ep : 4; // 10..13 Number of device endpoints (excluding EP0) + uint32_t num_host_ch : 4; // 14..17 Number of host channel (excluding control) + uint32_t period_channel_support : 1; // 18 Support Periodic OUT Host Channel + uint32_t enable_dynamic_fifo : 1; // 19 Dynamic FIFO Sizing Enabled + uint32_t mul_cpu_int : 1; // 20 Multi-Processor Interrupt Enabled + uint32_t reserved21 : 1; // 21 reserved + uint32_t nptx_q_depth : 2; // 22..23 Non-periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 + uint32_t ptx_q_depth : 2; // 24..25 Host periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 + uint32_t token_q_depth : 5; // 26..30 Device IN token sequence learning queue depth: 0-30 + uint32_t otg_enable_ic_usb : 1; // 31 IC_USB mode specified for mode of operation +} dwc2_ghwcfg2_t; +TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg2_t) == 4, "incorrect size"); + +typedef struct TU_ATTR_PACKED { + uint32_t xfer_size_width : 4; // 0..3 Transfer size counter in bits = 11 + n (max 19 bits) + uint32_t packet_size_width : 3; // 4..6 Packet size counter in bits = 4 + n (max 10 bits) + uint32_t otg_enable : 1; // 7 OTG capable + uint32_t i2c_enable : 1; // 8 I2C interface is available + uint32_t vendor_ctrl_itf : 1; // 9 Vendor control interface is available + uint32_t optional_feature_removed : 1; // 10 remove User ID, GPIO, SOF toggle & counter to save gate count + uint32_t synch_reset : 1; // 11 0: async reset | 1: synch reset + uint32_t otg_adp_support : 1; // 12 ADP logic is present along with HSOTG controller + uint32_t otg_enable_hsic : 1; // 13 1: HSIC-capable with shared UTMI PHY interface | 0: non-HSIC + uint32_t battery_charger_support : 1; // s14 upport battery charger + uint32_t lpm_mode : 1; // 15 LPM mode + uint32_t dfifo_depth : 16; // DFIFO depth - EP_LOC_CNT in terms of 32-bit words +}dwc2_ghwcfg3_t; +TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg3_t) == 4, "incorrect size"); + +typedef struct TU_ATTR_PACKED { + uint32_t num_dev_period_in_ep : 4; // 0..3 Number of Device Periodic IN Endpoints + uint32_t partial_powerdown : 1; // 4 Partial Power Down Enabled + uint32_t ahb_freq_min : 1; // 5 1: minimum of AHB frequency is less than 60 MHz + uint32_t hibernation : 1; // 6 Hibernation feature is enabled + uint32_t extended_hibernation : 1; // 7 Extended Hibernation feature is enabled + uint32_t reserved8 : 1; // 8 Reserved + uint32_t enhanced_lpm_support1 : 1; // 9 Enhanced LPM Support1 + uint32_t service_interval_flow : 1; // 10 Service Interval flow is supported + uint32_t ipg_isoc_support : 1; // 11 Interpacket GAP ISO OUT worst-case is supported + uint32_t acg_support : 1; // 12 Active clock gating is supported + uint32_t enhanced_lpm_support : 1; // 13 Enhanced LPM Support + uint32_t phy_data_width : 2; // 14..15 0: 8 bits | 1: 16 bits | 2: 8/16 software selectable + uint32_t ctrl_ep_num : 4; // 16..19 Number of Device control endpoints in addition to EP0 + uint32_t iddg_filter : 1; // 20 IDDG Filter Enabled + uint32_t vbus_valid_filter : 1; // 21 VBUS Valid Filter Enabled + uint32_t a_valid_filter : 1; // 22 A Valid Filter Enabled + uint32_t b_valid_filter : 1; // 23 B Valid Filter Enabled + uint32_t session_end_filter : 1; // 24 Session End Filter Enabled + uint32_t dedicated_fifos : 1; // 25 Dedicated tx fifo for device IN Endpoint + uint32_t num_dev_in_eps : 4; // 26..29 Number of Device IN Endpoints including EP0 + uint32_t dma_desc_enabled : 1; // scatter/gather DMA configuration enabled + uint32_t dma_desc_dynamic : 1; // Dynamic scatter/gather DMA +}dwc2_ghwcfg4_t; +TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg4_t) == 4, "incorrect size"); + // Host Channel typedef struct { volatile uint32_t hcchar; // 500 + 20*ch Host Channel Characteristics @@ -306,103 +340,103 @@ typedef struct { // CSR Register Map //-------------------------------------------------------------------- typedef struct { - //------------- Core Global -------------// - volatile uint32_t gotgctl; // 000 OTG Control and Status - volatile uint32_t gotgint; // 004 OTG Interrupt - volatile uint32_t gahbcfg; // 008 AHB Configuration - volatile uint32_t gusbcfg; // 00c USB Configuration - volatile uint32_t grstctl; // 010 Reset - volatile uint32_t gintsts; // 014 Interrupt - volatile uint32_t gintmsk; // 018 Interrupt Mask - volatile uint32_t grxstsr; // 01c Receive Status Debug Read - volatile uint32_t grxstsp; // 020 Receive Status Read/Pop - volatile uint32_t grxfsiz; // 024 Receive FIFO Size -union { - volatile uint32_t dieptxf0; // 028 EP0 Tx FIFO Size - volatile uint32_t gnptxfsiz; // 028 Non-periodic Transmit FIFO Size -}; - volatile uint32_t gnptxsts; // 02c Non-periodic Transmit FIFO/Queue Status - volatile uint32_t gi2cctl; // 030 I2C Address - volatile uint32_t gpvndctl; // 034 PHY Vendor Control -union { - volatile uint32_t ggpio; // 038 General Purpose IO - volatile uint32_t stm32_gccfg; // 038 STM32 General Core Configuration -}; - volatile uint32_t guid; // 03C User (Application programmable) ID - volatile uint32_t gsnpsid; // 040 Synopsys ID + Release version - volatile uint32_t ghwcfg1; // 044 User Hardware Configuration1: endpoint dir (2 bit per ep) -union { - volatile uint32_t ghwcfg2; // 048 User Hardware Configuration2 - volatile dwc2_ghwcfg2_t ghwcfg2_bm; -}; -union { - volatile uint32_t ghwcfg3; // 04C User Hardware Configuration3 - volatile dwc2_ghwcfg3_t ghwcfg3_bm; -}; -union { - volatile uint32_t ghwcfg4; // 050 User Hardware Configuration4 - volatile dwc2_ghwcfg4_t ghwcfg4_bm; -}; - volatile uint32_t glpmcfg; // 054 Core LPM Configuration - volatile uint32_t gpwrdn; // 058 Power Down - volatile uint32_t gdfifocfg; // 05C DFIFO Software Configuration - volatile uint32_t gadpctl; // 060 ADP Timer, Control and Status - uint32_t reserved64[39]; // 064..0FF - volatile uint32_t hptxfsiz; // 100 Host Periodic Tx FIFO Size - volatile uint32_t dieptxf[15]; // 104..13C Device Periodic Transmit FIFO Size - uint32_t reserved140[176]; // 140..3FF - - //------------- Host -------------// - volatile uint32_t hcfg; // 400 Host Configuration - volatile uint32_t hfir; // 404 Host Frame Interval - volatile uint32_t hfnum; // 408 Host Frame Number / Frame Remaining - uint32_t reserved40c; // 40C - volatile uint32_t hptxsts; // 410 Host Periodic TX FIFO / Queue Status - volatile uint32_t haint; // 414 Host All Channels Interrupt - volatile uint32_t haintmsk; // 418 Host All Channels Interrupt Mask - volatile uint32_t hflbaddr; // 41C Host Frame List Base Address - uint32_t reserved420[8]; // 420..43F - volatile uint32_t hprt; // 440 Host Port Control and Status - uint32_t reserved444[47]; // 444..4FF - - //------------- Host Channel -------------// - dwc2_channel_t channel[16]; // 500..6FF Host Channels 0-15 - uint32_t reserved700[64]; // 700..7FF - - //------------- Device -------------// - volatile uint32_t dcfg; // 800 Device Configuration - volatile uint32_t dctl; // 804 Device Control - volatile uint32_t dsts; // 808 Device Status (RO) - uint32_t reserved80c; // 80C - volatile uint32_t diepmsk; // 810 Device IN Endpoint Interrupt Mask - volatile uint32_t doepmsk; // 814 Device OUT Endpoint Interrupt Mask - volatile uint32_t daint; // 818 Device All Endpoints Interrupt - volatile uint32_t daintmsk; // 81C Device All Endpoints Interrupt Mask - volatile uint32_t dtknqr1; // 820 Device IN token sequence learning queue read1 - volatile uint32_t dtknqr2; // 824 Device IN token sequence learning queue read2 - volatile uint32_t dvbusdis; // 828 Device VBUS Discharge Time - volatile uint32_t dvbuspulse; // 82C Device VBUS Pulsing Time - volatile uint32_t dthrctl; // 830 Device threshold Control - volatile uint32_t diepempmsk; // 834 Device IN Endpoint FIFO Empty Interrupt Mask - volatile uint32_t deachint; // 838 Device Each Endpoint Interrupt - volatile uint32_t deachmsk; // 83C Device Each Endpoint Interrupt msk - volatile uint32_t diepeachmsk[16]; // 840..87C Device Each IN Endpoint mask - volatile uint32_t doepeachmsk[16]; // 880..8BF Device Each OUT Endpoint mask - uint32_t reserved8c0[16]; // 8C0..8FF - - //------------- Device Endpoint -------------// - dwc2_epin_t epin[16]; // 900..AFF IN Endpoints - dwc2_epout_t epout[16]; // B00..CFF OUT Endpoints - uint32_t reservedd00[64]; // D00..DFF - - //------------- Power Clock -------------// - volatile uint32_t pcgctl; // E00 Power and Clock Gating Control - volatile uint32_t pcgctl1; // E04 - uint32_t reservede08[126]; // E08..FFF - - //------------- FIFOs -------------// - // Word-accessed only using first pointer since it auto shift - volatile uint32_t fifo[16][0x400]; // 1000..FFFF Endpoint FIFO + //------------- Core Global -------------// + volatile uint32_t gotgctl; // 000 OTG Control and Status + volatile uint32_t gotgint; // 004 OTG Interrupt + volatile uint32_t gahbcfg; // 008 AHB Configuration + volatile uint32_t gusbcfg; // 00c USB Configuration + volatile uint32_t grstctl; // 010 Reset + volatile uint32_t gintsts; // 014 Interrupt + volatile uint32_t gintmsk; // 018 Interrupt Mask + volatile uint32_t grxstsr; // 01c Receive Status Debug Read + volatile uint32_t grxstsp; // 020 Receive Status Read/Pop + volatile uint32_t grxfsiz; // 024 Receive FIFO Size + union { + volatile uint32_t dieptxf0; // 028 EP0 Tx FIFO Size + volatile uint32_t gnptxfsiz; // 028 Non-periodic Transmit FIFO Size + }; + volatile uint32_t gnptxsts; // 02c Non-periodic Transmit FIFO/Queue Status + volatile uint32_t gi2cctl; // 030 I2C Address + volatile uint32_t gpvndctl; // 034 PHY Vendor Control + union { + volatile uint32_t ggpio; // 038 General Purpose IO + volatile uint32_t stm32_gccfg; // 038 STM32 General Core Configuration + }; + volatile uint32_t guid; // 03C User (Application programmable) ID + volatile uint32_t gsnpsid; // 040 Synopsys ID + Release version + volatile uint32_t ghwcfg1; // 044 User Hardware Configuration1: endpoint dir (2 bit per ep) + union { + volatile uint32_t ghwcfg2; // 048 User Hardware Configuration2 + volatile dwc2_ghwcfg2_t ghwcfg2_bm; + }; + union { + volatile uint32_t ghwcfg3; // 04C User Hardware Configuration3 + volatile dwc2_ghwcfg3_t ghwcfg3_bm; + }; + union { + volatile uint32_t ghwcfg4; // 050 User Hardware Configuration4 + volatile dwc2_ghwcfg4_t ghwcfg4_bm; + }; + volatile uint32_t glpmcfg; // 054 Core LPM Configuration + volatile uint32_t gpwrdn; // 058 Power Down + volatile uint32_t gdfifocfg; // 05C DFIFO Software Configuration + volatile uint32_t gadpctl; // 060 ADP Timer, Control and Status + uint32_t reserved64[39]; // 064..0FF + volatile uint32_t hptxfsiz; // 100 Host Periodic Tx FIFO Size + volatile uint32_t dieptxf[15]; // 104..13C Device Periodic Transmit FIFO Size + uint32_t reserved140[176]; // 140..3FF + + //------------ Host -------------// + volatile uint32_t hcfg; // 400 Host Configuration + volatile uint32_t hfir; // 404 Host Frame Interval + volatile uint32_t hfnum; // 408 Host Frame Number / Frame Remaining + uint32_t reserved40c; // 40C + volatile uint32_t hptxsts; // 410 Host Periodic TX FIFO / Queue Status + volatile uint32_t haint; // 414 Host All Channels Interrupt + volatile uint32_t haintmsk; // 418 Host All Channels Interrupt Mask + volatile uint32_t hflbaddr; // 41C Host Frame List Base Address + uint32_t reserved420[8]; // 420..43F + volatile uint32_t hprt; // 440 Host Port Control and Status + uint32_t reserved444[47]; // 444..4FF + + //------------- Host Channel -------------// + dwc2_channel_t channel[16]; // 500..6FF Host Channels 0-15 + uint32_t reserved700[64]; // 700..7FF + + //------------- Device -----------// + volatile uint32_t dcfg; // 800 Device Configuration + volatile uint32_t dctl; // 804 Device Control + volatile uint32_t dsts; // 808 Device Status (RO) + uint32_t reserved80c; // 80C + volatile uint32_t diepmsk; // 810 Device IN Endpoint Interrupt Mask + volatile uint32_t doepmsk; // 814 Device OUT Endpoint Interrupt Mask + volatile uint32_t daint; // 818 Device All Endpoints Interrupt + volatile uint32_t daintmsk; // 81C Device All Endpoints Interrupt Mask + volatile uint32_t dtknqr1; // 820 Device IN token sequence learning queue read1 + volatile uint32_t dtknqr2; // 824 Device IN token sequence learning queue read2 + volatile uint32_t dvbusdis; // 828 Device VBUS Discharge Time + volatile uint32_t dvbuspulse; // 82C Device VBUS Pulsing Time + volatile uint32_t dthrctl; // 830 Device threshold Control + volatile uint32_t diepempmsk; // 834 Device IN Endpoint FIFO Empty Interrupt Mask + volatile uint32_t deachint; // 838 Device Each Endpoint Interrupt + volatile uint32_t deachmsk; // 83C Device Each Endpoint Interrupt msk + volatile uint32_t diepeachmsk[16]; // 840..87C Device Each IN Endpoint mask + volatile uint32_t doepeachmsk[16]; // 880..8BF Device Each OUT Endpoint mask + uint32_t reserved8c0[16]; // 8C0..8FF + + //------------- Device Endpoint -------------// + dwc2_epin_t epin[16]; // 900..AFF IN Endpoints + dwc2_epout_t epout[16]; // B00..CFF OUT Endpoints + uint32_t reservedd00[64]; // D00..DFF + + //------------- Power Clock -------------// + volatile uint32_t pcgctl; // E00 Power and Clock Gating Control + volatile uint32_t pcgctl1; // E04 + uint32_t reservede08[126]; // E08..FFF + + //------------- FIFOs -------------// + // Word-accessed only using first pointer since it auto shift + volatile uint32_t fifo[16][0x400]; // 1000..FFFF Endpoint FIFO } dwc2_regs_t; TU_VERIFY_STATIC(offsetof(dwc2_regs_t, hcfg ) == 0x0400, "incorrect size"); -- cgit v1.3.1 From 7e472fa3cacdd97e0329faa4dbc53a6d457a77f2 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 25 Sep 2024 17:18:41 +0700 Subject: try to add esp32 p4 and esp-idf v5.3 support --- hw/bsp/espressif/boards/CMakeLists.txt | 2 +- hw/bsp/espressif/boards/family.c | 135 +++++++++++++++++++++------------ src/common/tusb_mcu.h | 6 ++ src/tusb_option.h | 1 + 4 files changed, 93 insertions(+), 51 deletions(-) diff --git a/hw/bsp/espressif/boards/CMakeLists.txt b/hw/bsp/espressif/boards/CMakeLists.txt index 8209e8747..fe1273d4c 100644 --- a/hw/bsp/espressif/boards/CMakeLists.txt +++ b/hw/bsp/espressif/boards/CMakeLists.txt @@ -2,7 +2,7 @@ set(hw_dir "${CMAKE_CURRENT_LIST_DIR}/../../../") idf_component_register(SRCS family.c INCLUDE_DIRS "." ${BOARD} ${hw_dir} - PRIV_REQUIRES "driver" + PRIV_REQUIRES driver usb REQUIRES led_strip src tinyusb_src) target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format) diff --git a/hw/bsp/espressif/boards/family.c b/hw/bsp/espressif/boards/family.c index 02e478a0c..a1b4334b2 100644 --- a/hw/bsp/espressif/boards/family.c +++ b/hw/bsp/espressif/boards/family.c @@ -31,20 +31,9 @@ #include "esp_mac.h" #include "hal/gpio_ll.h" -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) -#include "hal/usb_hal.h" -#include "soc/usb_periph.h" -static void configure_pins(usb_hal_context_t* usb); -#endif - #include "driver/gpio.h" #include "driver/uart.h" - -#if ESP_IDF_VERSION_MAJOR > 4 - #include "esp_private/periph_ctrl.h" -#else - #include "driver/periph_ctrl.h" -#endif +#include "esp_private/periph_ctrl.h" // Note; current code use UART0 can cause device to reset while monitoring #define USE_UART 0 @@ -60,6 +49,7 @@ static led_strip_handle_t led_strip; static void max3421_init(void); #endif +static bool usb_init(void); //--------------------------------------------------------------------+ // Implementation @@ -111,16 +101,8 @@ void board_init(void) { gpio_set_direction(BUTTON_PIN, GPIO_MODE_INPUT); gpio_set_pull_mode(BUTTON_PIN, BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN_ONLY : GPIO_PULLUP_ONLY); -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) - // USB Controller Hal init - periph_module_reset(PERIPH_USB_MODULE); - periph_module_enable(PERIPH_USB_MODULE); - - usb_hal_context_t hal = { - .use_external_phy = false // use built-in PHY - }; - usb_hal_init(&hal); - configure_pins(&hal); +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_ESP32P4) + usb_init(); #endif #if CFG_TUH_ENABLED && CFG_TUH_MAX3421 @@ -129,35 +111,7 @@ void board_init(void) { } #if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) -static void configure_pins(usb_hal_context_t* usb) { - /* usb_periph_iopins currently configures USB_OTG as USB Device. - * Introduce additional parameters in usb_hal_context_t when adding support - * for USB Host. */ - for (const usb_iopin_dsc_t* iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) { - if ((usb->use_external_phy) || (iopin->ext_phy_only == 0)) { - esp_rom_gpio_pad_select_gpio(iopin->pin); - if (iopin->is_output) { - esp_rom_gpio_connect_out_signal(iopin->pin, iopin->func, false, false); - } else { - esp_rom_gpio_connect_in_signal(iopin->pin, iopin->func, false); -#if ESP_IDF_VERSION_MAJOR > 4 - if ((iopin->pin != GPIO_MATRIX_CONST_ZERO_INPUT) && (iopin->pin != GPIO_MATRIX_CONST_ONE_INPUT)) -#else - if ((iopin->pin != GPIO_FUNC_IN_LOW) && (iopin->pin != GPIO_FUNC_IN_HIGH)) -#endif - { - gpio_ll_input_enable(&GPIO, iopin->pin); - } - } - esp_rom_gpio_pad_unhold(iopin->pin); - } - } - if (!usb->use_external_phy) { - gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3); - gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3); - } -} #endif //--------------------------------------------------------------------+ @@ -204,6 +158,87 @@ int board_getchar(void) { return board_uart_read(&c, 1) > 0 ? (int) c : (-1); } +//-------------------------------------------------------------------- +// PHY Init +//-------------------------------------------------------------------- + +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_ESP32P4) +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0) + +#include "esp_private/usb_phy.h" +#include "soc/usb_pins.h" + +static usb_phy_handle_t phy_hdl; + +bool usb_init(void) { + // Configure USB PHY + usb_phy_config_t phy_conf = { + .controller = USB_PHY_CTRL_OTG, + .target = USB_PHY_TARGET_INT, + .otg_mode = USB_OTG_MODE_DEVICE, + }; + + // OTG IOs config + // const usb_phy_otg_io_conf_t otg_io_conf = USB_PHY_SELF_POWERED_DEVICE(config->vbus_monitor_io); + // if (config->self_powered) { + // phy_conf.otg_io_conf = &otg_io_conf; + // } + // ESP_RETURN_ON_ERROR(usb_new_phy(&phy_conf, &phy_hdl), TAG, "Install USB PHY failed"); + + usb_new_phy(&phy_conf, &phy_hdl); + + return true; +} + +#else + +#include "esp_private/usb_phy.h" +#include "hal/usb_hal.h" +#include "soc/usb_periph.h" + +static void configure_pins(usb_hal_context_t* usb) { + /* usb_periph_iopins currently configures USB_OTG as USB Device. + * Introduce additional parameters in usb_hal_context_t when adding support + * for USB Host. */ + for (const usb_iopin_dsc_t* iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) { + if ((usb->use_external_phy) || (iopin->ext_phy_only == 0)) { + esp_rom_gpio_pad_select_gpio(iopin->pin); + if (iopin->is_output) { + esp_rom_gpio_connect_out_signal(iopin->pin, iopin->func, false, false); + } else { + esp_rom_gpio_connect_in_signal(iopin->pin, iopin->func, false); + if ((iopin->pin != GPIO_MATRIX_CONST_ZERO_INPUT) && (iopin->pin != GPIO_MATRIX_CONST_ONE_INPUT)) { + gpio_ll_input_enable(&GPIO, iopin->pin); + } + } + esp_rom_gpio_pad_unhold(iopin->pin); + } + } + + if (!usb->use_external_phy) { + gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3); + gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3); + } +} + +bool usb_init(void) { + // USB Controller Hal init + periph_module_reset(PERIPH_USB_MODULE); + periph_module_enable(PERIPH_USB_MODULE); + + usb_hal_context_t hal = { + .use_external_phy = false // use built-in PHY + }; + + usb_hal_init(&hal); + configure_pins(&hal); + + return true; +} + +#endif +#endif + //--------------------------------------------------------------------+ // API: SPI transfer with MAX3421E, must be implemented by application //--------------------------------------------------------------------+ diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 6ead1ea0b..26a8ee26b 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -339,6 +339,12 @@ #define TUP_USBIP_DWC2_ESP32 #define TUP_DCD_ENDPOINT_MAX 6 +#elif TU_CHECK_MCU(OPT_MCU_ESP32P4) + #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_ESP32 + #define TUP_RHPORT_HIGHSPEED 1 // 1 port FS, 1 port HS + #define TUP_DCD_ENDPOINT_MAX 8 // FS 6 ep, HS 8 ep + #elif TU_CHECK_MCU(OPT_MCU_ESP32, OPT_MCU_ESP32C2, OPT_MCU_ESP32C3, OPT_MCU_ESP32C6, OPT_MCU_ESP32H2) #if (CFG_TUD_ENABLED || !(defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)) #error "MCUs are only supported with CFG_TUH_MAX3421 enabled" diff --git a/src/tusb_option.h b/src/tusb_option.h index 17de9cd72..79f49636f 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -123,6 +123,7 @@ #define OPT_MCU_ESP32C6 904 ///< Espressif ESP32-C6 #define OPT_MCU_ESP32C2 905 ///< Espressif ESP32-C2 #define OPT_MCU_ESP32H2 906 ///< Espressif ESP32-H2 +#define OPT_MCU_ESP32P4 907 ///< Espressif ESP32-P4 #define TUP_MCU_ESPRESSIF (CFG_TUSB_MCU >= 900 && CFG_TUSB_MCU < 1000) // check if Espressif MCU // Dialog -- cgit v1.3.1 From 67e5577b428e70878d99c4f83039cef020a272cb Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 25 Sep 2024 20:36:16 +0700 Subject: added p4, seems to work well and enumerated --- .idea/cmake.xml | 9 +- .../boards/espressif_p4_function_ev/board.cmake | 2 + .../boards/espressif_p4_function_ev/board.h | 43 ++++++++ hw/bsp/espressif/family.cmake | 3 + src/common/tusb_mcu.h | 6 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 23 ++-- src/portable/synopsys/dwc2/dwc2_esp32.h | 48 +++++++-- src/portable/synopsys/dwc2/dwc2_info.md | 116 ++++++++++----------- src/portable/synopsys/dwc2/dwc2_info.py | 1 + 9 files changed, 164 insertions(+), 87 deletions(-) create mode 100644 hw/bsp/espressif/boards/espressif_p4_function_ev/board.cmake create mode 100644 hw/bsp/espressif/boards/espressif_p4_function_ev/board.h diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 96ff19c89..b6a237a1d 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -37,7 +37,7 @@ - + @@ -145,6 +145,13 @@ + + + + + + + \ No newline at end of file diff --git a/hw/bsp/espressif/boards/espressif_p4_function_ev/board.cmake b/hw/bsp/espressif/boards/espressif_p4_function_ev/board.cmake new file mode 100644 index 000000000..fe4db4fc1 --- /dev/null +++ b/hw/bsp/espressif/boards/espressif_p4_function_ev/board.cmake @@ -0,0 +1,2 @@ +# Apply board specific content here +set(IDF_TARGET "esp32p4") diff --git a/hw/bsp/espressif/boards/espressif_p4_function_ev/board.h b/hw/bsp/espressif/boards/espressif_p4_function_ev/board.h new file mode 100644 index 000000000..9c8aa409f --- /dev/null +++ b/hw/bsp/espressif/boards/espressif_p4_function_ev/board.h @@ -0,0 +1,43 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// #define NEOPIXEL_PIN 48 + +#define BUTTON_PIN 0 +#define BUTTON_STATE_ACTIVE 0 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/espressif/family.cmake b/hw/bsp/espressif/family.cmake index eb97401c3..b0786f1cc 100644 --- a/hw/bsp/espressif/family.cmake +++ b/hw/bsp/espressif/family.cmake @@ -8,4 +8,7 @@ string(TOUPPER ${IDF_TARGET} FAMILY_MCUS) # Add example src and bsp directories set(EXTRA_COMPONENT_DIRS "src" "${CMAKE_CURRENT_LIST_DIR}/boards" "${CMAKE_CURRENT_LIST_DIR}/components") +# set SDKCONFIG for each IDF Target +set(SDKCONFIG ${CMAKE_SOURCE_DIR}/sdkconfig.${IDF_TARGET}) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 26a8ee26b..6b19ac9fe 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -337,13 +337,13 @@ #elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_ESP32 - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 7 // only 5 TX FIFO for endpoint IN #elif TU_CHECK_MCU(OPT_MCU_ESP32P4) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_ESP32 - #define TUP_RHPORT_HIGHSPEED 1 // 1 port FS, 1 port HS - #define TUP_DCD_ENDPOINT_MAX 8 // FS 6 ep, HS 8 ep + #define TUP_RHPORT_HIGHSPEED 1 // port0 FS, port1 HS + #define TUP_DCD_ENDPOINT_MAX 16 // FS 7 ep, HS 16 ep #elif TU_CHECK_MCU(OPT_MCU_ESP32, OPT_MCU_ESP32C2, OPT_MCU_ESP32C3, OPT_MCU_ESP32C6, OPT_MCU_ESP32H2) #if (CFG_TUD_ENABLED || !(defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 13143073d..d1eb22ed7 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -508,18 +508,6 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -#if CFG_TUSB_DEBUG >= DWC2_DEBUG -void print_dwc2_info(dwc2_regs_t* dwc2) { - // print guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 - // use dwc2_info.py/md for bit-field value and comparison with other ports - volatile uint32_t const* p = (volatile uint32_t const*) &dwc2->guid; - TU_LOG(DWC2_DEBUG, "guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4\r\n"); - for (size_t i = 0; i < 5; i++) { - TU_LOG(DWC2_DEBUG, "0x%08" PRIX32 ", ", p[i]); - } - TU_LOG(DWC2_DEBUG, "0x%08" PRIX32 "\r\n", p[5]); -} -#endif static void reset_core(dwc2_regs_t* dwc2) { // reset core @@ -633,8 +621,15 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { } static bool check_dwc2(dwc2_regs_t* dwc2) { -#if CFG_TUSB_DEBUG >= DWC2_DEBUG - print_dwc2_info(dwc2); +#if CFG_TUSB_DEBUG >= DWC2_DEBUG || 1 + // print guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 + // Run 'dwc2_info.py render-md' and check dwc2_info.md for bit-field value and comparison with other ports + volatile uint32_t const* p = (volatile uint32_t const*) &dwc2->guid; + TU_LOG1("guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4\r\n"); + for (size_t i = 0; i < 5; i++) { + TU_LOG1("0x%08" PRIX32 ", ", p[i]); + } + TU_LOG1("0x%08" PRIX32 "\r\n", p[5]); #endif // For some reason: GD32VF103 snpsid and all hwcfg register are always zero (skip it) diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index 921cee29e..af04347d1 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -38,29 +38,55 @@ #include "soc/periph_defs.h" #include "soc/usb_wrap_struct.h" -#define DWC2_REG_BASE 0x60080000UL -#define DWC2_EP_MAX 7 -#define DWC2_EP_IN_MAX 5 +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#define DWC2_PERIPH_COUNT 1 +#define DWC2_FS_REG_BASE 0x60080000UL +#define DWC2_EP_MAX 7 static const dwc2_controller_t _dwc2_controller[] = { - { .reg_base = DWC2_REG_BASE, .irqnum = 0, .ep_count = DWC2_EP_MAX, .ep_in_count = DWC2_EP_IN_MAX, .ep_fifo_size = 1024 } + { .reg_base = DWC2_FS_REG_BASE, .irqnum = ETS_USB_INTR_SOURCE, .ep_count = 7, .ep_in_count = 5, .ep_fifo_size = 1024 } }; -static intr_handle_t usb_ih; +#elif TU_CHECK_MCU(OPT_MCU_ESP32P4) + +#define DWC2_PERIPH_COUNT 2 +#define DWC2_FS_REG_BASE 0x50040000UL +#define DWC2_HS_REG_BASE 0x50000000UL +#define DWC2_EP_MAX 16 + +// On ESP32 for consistency we associate +// - Port0 to OTG_FS, and Port1 to OTG_HS +static const dwc2_controller_t _dwc2_controller[] = { + { + .reg_base = DWC2_HS_REG_BASE, .irqnum = ETS_USB_OTG_INTR_SOURCE, .ep_count = 16, .ep_in_count = 8, + .ep_fifo_size = 4096 + }, +{ + .reg_base = DWC2_FS_REG_BASE, .irqnum = ETS_USB_OTG11_CH0_INTR_SOURCE, .ep_count = 7, .ep_in_count = 5, + .ep_fifo_size = 1024 +} + +}; +#endif + +enum { + DWC2_CONTROLLER_COUNT = TU_ARRAY_SIZE(_dwc2_controller) +}; + +static intr_handle_t usb_ih[DWC2_CONTROLLER_COUNT]; static void dcd_int_handler_wrap(void* arg) { - (void)arg; - dcd_int_handler(0); + const uint8_t rhport = (uint8_t) arg; + dcd_int_handler(rhport); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { - (void)rhport; - esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, dcd_int_handler_wrap, NULL, &usb_ih); + esp_intr_alloc(_dwc2_controller[rhport].irqnum, ESP_INTR_FLAG_LOWMED, + dcd_int_handler_wrap, (void*) rhport, &usb_ih[rhport]); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable(uint8_t rhport) { - (void)rhport; - esp_intr_free(usb_ih); + esp_intr_free(usb_ih[rhport]); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) { diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index 9798fb0de..462b5856a 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -1,58 +1,58 @@ -| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | STM32F 407/411/429 FS | STM32F 407/429 HS | STM32F 412/767 FS | STM32F723 FS | STM32F723 HS | STM32H743 HS | STM32L476 FS | STM32U5A5 HS | GD32VF103 FS | XMC4500 | -|:---------------------------|:----------------|:-------------|:--------------|:------------------------|:--------------------|:--------------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:-----------| -| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | -| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | -| - specs version | 2.80a | 3.30a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | -| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | -| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | -| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | -| - arch | 2 | 2 | 2 | 0 | 2 | 0 | 0 | 2 | 2 | 0 | 2 | 0 | 2 | -| - point2point | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | -| - hs_phy_type | 1 | 0 | 0 | 0 | 2 | 0 | 0 | 3 | 2 | 0 | 1 | 0 | 0 | -| - fs_phy_type | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - num_dev_ep | 7 | 6 | 6 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | -| - num_host_ch | 7 | 13 | 7 | 7 | 11 | 11 | 11 | 15 | 15 | 11 | 15 | 0 | 13 | -| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - nptx_q_depth | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - ptx_q_depth | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | -| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | -| - xfer_size_width | 8 | 8 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | -| - packet_size_width | 6 | 6 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | -| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - i2c_enable | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | -| - vendor_ctrl_itf | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | -| - optional_feature_removed | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | -| - dfifo_depth | 4080 | 498 | 200 | 512 | 1012 | 512 | 512 | 1006 | 952 | 512 | 952 | 0 | 634 | -| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | -| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - enhanced_lpm_support | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - phy_data_width | 0 | 2 | 2 | 2 | 0 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 2 | -| - ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - num_dev_in_eps | 7 | 6 | 4 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | -| - dma_desc_enable | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | -| - dma_desc_dynamic | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | ESP32-P4 | STM32F 407/411/429 FS | STM32F 407/429 HS | STM32F 412/767 FS | STM32F723 FS | STM32F723 HS | STM32H743 HS | STM32L476 FS | STM32U5A5 HS | GD32VF103 FS | XMC4500 | +|:---------------------------|:----------------|:-------------|:--------------|:-----------|:------------------------|:--------------------|:--------------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:-----------| +| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | +| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | +| - specs version | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | +| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | +| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | +| - arch | 2 | 2 | 2 | 2 | 0 | 2 | 0 | 0 | 2 | 2 | 0 | 2 | 0 | 2 | +| - point2point | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | +| - hs_phy_type | 1 | 0 | 0 | 3 | 0 | 2 | 0 | 0 | 3 | 2 | 0 | 1 | 0 | 0 | +| - fs_phy_type | 1 | 1 | 1 | 3 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - num_dev_ep | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | +| - num_host_ch | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 11 | 15 | 0 | 13 | +| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - nptx_q_depth | 2 | 2 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - ptx_q_depth | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | +| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | +| - xfer_size_width | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | +| - packet_size_width | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | +| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - i2c_enable | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | +| - vendor_ctrl_itf | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | +| - optional_feature_removed | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - synch_reset | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - otg_adp_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - battery_charger_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | +| - dfifo_depth | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 952 | 512 | 952 | 0 | 634 | +| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | +| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - enhanced_lpm_support | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - phy_data_width | 0 | 2 | 2 | 2 | 2 | 0 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 2 | +| - ctrl_ep_num | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - num_dev_in_eps | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | +| - dma_desc_enable | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| - dma_desc_dynamic | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index 871ac112d..e382ba011 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -9,6 +9,7 @@ dwc2_reg_value = { 'BCM2711 (Pi4)': [0x2708A000, 0x4F54280A, 0, 0x228DDD50, 0xFF000E8, 0x1FF00020], 'EFM32GG FS': [0, 0x4F54330A, 0, 0x228F5910, 0x1F204E8, 0x1BF08030], 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0xC804B5, 0xD3F0A030], + 'ESP32-P4': [0, 0x4F54400A, 0, 0x215FFFD0, 0x03805EB5, 0xDFF1A030], 'STM32F 407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], 'STM32F 407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], 'STM32F 412/767 FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], -- cgit v1.3.1 From 87f199330405f0a51f8ad4b3b8b2d69c9a21ac3e Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 Sep 2024 15:32:47 +0700 Subject: esp32p4 use port0 as fs, port1 as highspeed --- .idea/cmake.xml | 16 +++++----- hw/bsp/espressif/boards/CMakeLists.txt | 2 -- .../components/tinyusb_src/CMakeLists.txt | 3 ++ hw/bsp/espressif/family.cmake | 10 +++++- src/portable/synopsys/dwc2/dcd_dwc2.c | 30 +++++++++++++----- src/portable/synopsys/dwc2/dwc2_esp32.h | 36 ++++++---------------- 6 files changed, 52 insertions(+), 45 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index b6a237a1d..37cd73c65 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -37,7 +37,7 @@ - + @@ -65,6 +65,13 @@ + + + + + + + @@ -145,13 +152,6 @@ - - - - - - - \ No newline at end of file diff --git a/hw/bsp/espressif/boards/CMakeLists.txt b/hw/bsp/espressif/boards/CMakeLists.txt index fe1273d4c..434f77704 100644 --- a/hw/bsp/espressif/boards/CMakeLists.txt +++ b/hw/bsp/espressif/boards/CMakeLists.txt @@ -4,5 +4,3 @@ idf_component_register(SRCS family.c INCLUDE_DIRS "." ${BOARD} ${hw_dir} PRIV_REQUIRES driver usb REQUIRES led_strip src tinyusb_src) - -target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format) diff --git a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt index 8bdb3802e..26c7e4030 100644 --- a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt +++ b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt @@ -9,6 +9,9 @@ string(TOUPPER OPT_MCU_${target} tusb_mcu) list(APPEND compile_definitions CFG_TUSB_MCU=${tusb_mcu} CFG_TUSB_OS=OPT_OS_FREERTOS + # EXAMPLE port selection: port0 is fullspeed, port1 is highspeed + BOARD_TUD_RHPORT=${TUD_PORT} + BOARD_TUD_MAX_SPEED=$ ) list(APPEND srcs diff --git a/hw/bsp/espressif/family.cmake b/hw/bsp/espressif/family.cmake index b0786f1cc..ada082c76 100644 --- a/hw/bsp/espressif/family.cmake +++ b/hw/bsp/espressif/family.cmake @@ -2,9 +2,17 @@ cmake_minimum_required(VERSION 3.5) # Apply board specific content i.e IDF_TARGET must be set before project.cmake is included include("${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake") - string(TOUPPER ${IDF_TARGET} FAMILY_MCUS) +# Device port default to Port1 for P4 (highspeed), Port0 for others (fullspeed) +if (NOT DEFINED TUD_PORT) + if (IDF_TARGET STREQUAL "esp32p4") + set(TUD_PORT 1) + else () + set(TUD_PORT 0) + endif () +endif() + # Add example src and bsp directories set(EXTRA_COMPONENT_DIRS "src" "${CMAKE_CURRENT_LIST_DIR}/boards" "${CMAKE_CURRENT_LIST_DIR}/components") diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index d1eb22ed7..4fa869241 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -31,6 +31,9 @@ #if CFG_TUD_ENABLED && defined(TUP_USBIP_DWC2) +// Debug level for DWC2 +#define DWC2_DEBUG 2 + #include "device/dcd.h" #include "dwc2_type.h" @@ -57,15 +60,24 @@ #error "Unsupported MCUs" #endif -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM -//--------------------------------------------------------------------+ +enum { + DWC2_CONTROLLER_COUNT = TU_ARRAY_SIZE(_dwc2_controller) +}; // DWC2 registers -#define DWC2_REG(_port) ((dwc2_regs_t*) _dwc2_controller[_port].reg_base) +//#define DWC2_REG(_port) ((dwc2_regs_t*) _dwc2_controller[_port].reg_base) -// Debug level for DWC2 -#define DWC2_DEBUG 2 +TU_ATTR_ALWAYS_INLINE static inline dwc2_regs_t* DWC2_REG(uint8_t rhport) { + if (rhport >= DWC2_CONTROLLER_COUNT) { + // user mis-configured, ignore and use first controller + rhport = 0; + } + return (dwc2_regs_t*) _dwc2_controller[rhport].reg_base; +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ static CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; @@ -584,7 +596,9 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { gusbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16); // Set 16-bit interface if supported - if (dwc2->ghwcfg4_bm.phy_data_width) gusbcfg |= GUSBCFG_PHYIF16; + if (dwc2->ghwcfg4_bm.phy_data_width) { + gusbcfg |= GUSBCFG_PHYIF16; + } } // Apply config @@ -621,7 +635,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { } static bool check_dwc2(dwc2_regs_t* dwc2) { -#if CFG_TUSB_DEBUG >= DWC2_DEBUG || 1 +#if CFG_TUSB_DEBUG >= DWC2_DEBUG // print guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 // Run 'dwc2_info.py render-md' and check dwc2_info.md for bit-field value and comparison with other ports volatile uint32_t const* p = (volatile uint32_t const*) &dwc2->guid; diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index af04347d1..4cdbcdb7a 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -39,50 +39,36 @@ #include "soc/usb_wrap_struct.h" #if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) -#define DWC2_PERIPH_COUNT 1 -#define DWC2_FS_REG_BASE 0x60080000UL -#define DWC2_EP_MAX 7 +#define DWC2_FS_REG_BASE 0x60080000UL +#define DWC2_EP_MAX 7 static const dwc2_controller_t _dwc2_controller[] = { { .reg_base = DWC2_FS_REG_BASE, .irqnum = ETS_USB_INTR_SOURCE, .ep_count = 7, .ep_in_count = 5, .ep_fifo_size = 1024 } }; #elif TU_CHECK_MCU(OPT_MCU_ESP32P4) - -#define DWC2_PERIPH_COUNT 2 -#define DWC2_FS_REG_BASE 0x50040000UL -#define DWC2_HS_REG_BASE 0x50000000UL -#define DWC2_EP_MAX 16 +#define DWC2_FS_REG_BASE 0x50040000UL +#define DWC2_HS_REG_BASE 0x50000000UL +#define DWC2_EP_MAX 16 // On ESP32 for consistency we associate // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { - { - .reg_base = DWC2_HS_REG_BASE, .irqnum = ETS_USB_OTG_INTR_SOURCE, .ep_count = 16, .ep_in_count = 8, - .ep_fifo_size = 4096 - }, -{ - .reg_base = DWC2_FS_REG_BASE, .irqnum = ETS_USB_OTG11_CH0_INTR_SOURCE, .ep_count = 7, .ep_in_count = 5, - .ep_fifo_size = 1024 -} - +{ .reg_base = DWC2_FS_REG_BASE, .irqnum = ETS_USB_OTG11_CH0_INTR_SOURCE, .ep_count = 7, .ep_in_count = 5, .ep_fifo_size = 1024 }, +{ .reg_base = DWC2_HS_REG_BASE, .irqnum = ETS_USB_OTG_INTR_SOURCE, .ep_count = 16, .ep_in_count = 8, .ep_fifo_size = 4096 } }; #endif -enum { - DWC2_CONTROLLER_COUNT = TU_ARRAY_SIZE(_dwc2_controller) -}; - -static intr_handle_t usb_ih[DWC2_CONTROLLER_COUNT]; +static intr_handle_t usb_ih[TU_ARRAY_SIZE(_dwc2_controller)]; static void dcd_int_handler_wrap(void* arg) { - const uint8_t rhport = (uint8_t) arg; + const uint8_t rhport = (uint8_t)(uintptr_t) arg; dcd_int_handler(rhport); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { esp_intr_alloc(_dwc2_controller[rhport].irqnum, ESP_INTR_FLAG_LOWMED, - dcd_int_handler_wrap, (void*) rhport, &usb_ih[rhport]); + dcd_int_handler_wrap, (void*)(uintptr_t) rhport, &usb_ih[rhport]); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable(uint8_t rhport) { @@ -97,7 +83,6 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) { TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; (void)hs_phy_type; - // nothing to do } @@ -105,7 +90,6 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; (void)hs_phy_type; - // nothing to do } -- cgit v1.3.1 From 4c81d91a736b0ab50bf263abb1f6248628cfa7f1 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 Sep 2024 21:36:47 +0700 Subject: bump up idf to 5.3.1 --- .circleci/config2.yml | 2 +- .github/workflows/build.yml | 2 +- .github/workflows/build_util.yml | 4 ++-- .github/workflows/ci_set_matrix.py | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.circleci/config2.yml b/.circleci/config2.yml index 278ff0f3b..5e73ab456 100644 --- a/.circleci/config2.yml +++ b/.circleci/config2.yml @@ -105,7 +105,7 @@ commands: name: Build command: | if [ << parameters.toolchain >> == esp-idf ]; then - docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python tools/build.py << parameters.family >> + docker run --rm -v $PWD:/project -w /project espressif/idf:v5.3.1 python tools/build.py << parameters.family >> else # Toolchain option default is gcc if [ << parameters.toolchain >> == arm-clang ]; then diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6ca9885f8..70bb3113f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -85,7 +85,7 @@ jobs: - 'msp430-gcc' - 'riscv-gcc' - 'rx-gcc' - - 'esp-idf' # buid-system is ignored + - 'esp-idf' # build-system is ignored with: build-system: 'make' toolchain: ${{ matrix.toolchain }} diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 294d18140..706ded1c1 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -41,7 +41,7 @@ jobs: uses: ./.github/actions/setup_toolchain with: toolchain: ${{ inputs.toolchain }} - toolchain_version: 'v5.1.1' + toolchain_version: 'v5.3.1' - name: Get Dependencies uses: ./.github/actions/get_deps @@ -61,7 +61,7 @@ jobs: - name: Build run: | if [ "${{ inputs.toolchain }}" == "esp-idf" ]; then - docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python tools/build.py ${{ matrix.arg }} + docker run --rm -v $PWD:/project -w /project espressif/idf:v5.3.1 python tools/build.py ${{ matrix.arg }} else python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} fi diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 4da26bfea..8974037e4 100644 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -45,6 +45,7 @@ family_list = { "xmc4000": ["arm-gcc"], "-bespressif_kaluga_1": ["esp-idf"], "-bespressif_s3_devkitm": ["esp-idf"], + "-bespressif_p4_function_ev": ["esp-idf"], } -- cgit v1.3.1 From 4617fb52296d2361bf848f7629d2d8be1aba5130 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 30 Sep 2024 21:53:57 +0700 Subject: update build script to correctly skip non max3421 enabled for espressif boards --- .../boards/adafruit_feather_esp32_v2/board.cmake | 1 + .../boards/adafruit_feather_esp32s2/board.cmake | 1 + .../boards/adafruit_feather_esp32s3/board.cmake | 3 ++ .../boards/adafruit_feather_esp32s3/board.h | 53 ++++++++++++++++++++++ .../boards/adafruit_metro_esp32s2/board.cmake | 1 + .../boards/espressif_c3_devkitc/board.cmake | 1 + .../boards/espressif_c6_devkitc/board.cmake | 1 + tools/build.py | 11 +++-- tools/build_utils.py | 44 +++++++++--------- 9 files changed, 89 insertions(+), 27 deletions(-) create mode 100644 hw/bsp/espressif/boards/adafruit_feather_esp32s3/board.cmake create mode 100644 hw/bsp/espressif/boards/adafruit_feather_esp32s3/board.h diff --git a/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake b/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake index 18c956714..84ea4940b 100644 --- a/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake +++ b/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake @@ -1,2 +1,3 @@ # Apply board specific content here set(IDF_TARGET "esp32") +set(MAX3421_HOST 1) diff --git a/hw/bsp/espressif/boards/adafruit_feather_esp32s2/board.cmake b/hw/bsp/espressif/boards/adafruit_feather_esp32s2/board.cmake index abbdf7abc..0bbf5a013 100644 --- a/hw/bsp/espressif/boards/adafruit_feather_esp32s2/board.cmake +++ b/hw/bsp/espressif/boards/adafruit_feather_esp32s2/board.cmake @@ -1,2 +1,3 @@ # Apply board specific content here set(IDF_TARGET "esp32s2") +set(MAX3421_HOST 1) diff --git a/hw/bsp/espressif/boards/adafruit_feather_esp32s3/board.cmake b/hw/bsp/espressif/boards/adafruit_feather_esp32s3/board.cmake new file mode 100644 index 000000000..dd204f0a4 --- /dev/null +++ b/hw/bsp/espressif/boards/adafruit_feather_esp32s3/board.cmake @@ -0,0 +1,3 @@ +# Apply board specific content here +set(IDF_TARGET "esp32s3") +set(MAX3421_HOST 1) diff --git a/hw/bsp/espressif/boards/adafruit_feather_esp32s3/board.h b/hw/bsp/espressif/boards/adafruit_feather_esp32s3/board.h new file mode 100644 index 000000000..9aa2e7535 --- /dev/null +++ b/hw/bsp/espressif/boards/adafruit_feather_esp32s3/board.h @@ -0,0 +1,53 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define NEOPIXEL_PIN 33 +#define NEOPIXEL_POWER_PIN 21 +#define NEOPIXEL_POWER_STATE 1 + +#define BUTTON_PIN 0 +#define BUTTON_STATE_ACTIVE 0 + +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI2_HOST +#define MAX3421_SCK_PIN 36 +#define MAX3421_MOSI_PIN 35 +#define MAX3421_MISO_PIN 37 +#define MAX3421_CS_PIN 10 +#define MAX3421_INTR_PIN 9 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.cmake b/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.cmake index abbdf7abc..0bbf5a013 100644 --- a/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.cmake +++ b/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.cmake @@ -1,2 +1,3 @@ # Apply board specific content here set(IDF_TARGET "esp32s2") +set(MAX3421_HOST 1) diff --git a/hw/bsp/espressif/boards/espressif_c3_devkitc/board.cmake b/hw/bsp/espressif/boards/espressif_c3_devkitc/board.cmake index ab4bc1a06..6a0060f9e 100644 --- a/hw/bsp/espressif/boards/espressif_c3_devkitc/board.cmake +++ b/hw/bsp/espressif/boards/espressif_c3_devkitc/board.cmake @@ -1,2 +1,3 @@ # Apply board specific content here set(IDF_TARGET "esp32c3") +set(MAX3421_HOST 1) diff --git a/hw/bsp/espressif/boards/espressif_c6_devkitc/board.cmake b/hw/bsp/espressif/boards/espressif_c6_devkitc/board.cmake index 50c7cb35d..9adaefb17 100644 --- a/hw/bsp/espressif/boards/espressif_c6_devkitc/board.cmake +++ b/hw/bsp/espressif/boards/espressif_c6_devkitc/board.cmake @@ -1,2 +1,3 @@ # Apply board specific content here set(IDF_TARGET "esp32c6") +set(MAX3421_HOST 1) diff --git a/tools/build.py b/tools/build.py index f9ae68231..44ac251de 100644 --- a/tools/build.py +++ b/tools/build.py @@ -84,10 +84,13 @@ def cmake_board(board, toolchain): # for espressif, we have to build example individually all_examples = get_examples(family) for example in all_examples: - rcmd = run_cmd(f'cmake examples/{example} -B {build_dir}/{example} -G "Ninja" -DBOARD={board} -DMAX3421_HOST=1') - if rcmd.returncode == 0: - rcmd = run_cmd(f'cmake --build {build_dir}/{example}') - ret[0 if rcmd.returncode == 0 else 1] += 1 + if build_utils.skip_example(example, board): + ret[2] += 1 + else: + rcmd = run_cmd(f'cmake examples/{example} -B {build_dir}/{example} -G "Ninja" -DBOARD={board}') + if rcmd.returncode == 0: + rcmd = run_cmd(f'cmake --build {build_dir}/{example}') + ret[0 if rcmd.returncode == 0 else 1] += 1 else: rcmd = run_cmd(f'cmake examples -B {build_dir} -G "Ninja" -DBOARD={board} -DCMAKE_BUILD_TYPE=MinSizeRel -DTOOLCHAIN={toolchain}') if rcmd.returncode == 0: diff --git a/tools/build_utils.py b/tools/build_utils.py index 5f88db8a2..265ab5c52 100644 --- a/tools/build_utils.py +++ b/tools/build_utils.py @@ -13,33 +13,25 @@ def skip_example(example, board): ex_dir = pathlib.Path('examples/') / example bsp = pathlib.Path("hw/bsp") - if (bsp / board / "board.mk").exists(): - # board without family - board_dir = bsp / board - family = "" - mk_contents = "" - else: - # board within family - board_dir = list(bsp.glob("*/boards/" + board)) - if not board_dir: - # Skip unknown boards - return True - - board_dir = list(board_dir)[0] + # board within family + board_dir = list(bsp.glob("*/boards/" + board)) + if not board_dir: + # Skip unknown boards + return True - family_dir = board_dir.parent.parent - family = family_dir.name + board_dir = list(board_dir)[0] + family_dir = board_dir.parent.parent + family = family_dir.name - # family.mk - family_mk = family_dir / "family.mk" - mk_contents = family_mk.read_text() + # family.mk + family_mk = family_dir / "family.mk" + mk_contents = family_mk.read_text() # Find the mcu, first in family mk then board mk if "CFG_TUSB_MCU=OPT_MCU_" not in mk_contents: - board_mk = board_dir / "board.cmake" + board_mk = board_dir / "board.mk" if not board_mk.exists(): - board_mk = board_dir / "board.mk" - + board_mk = board_dir / "board.cmake" mk_contents = board_mk.read_text() mcu = "NONE" @@ -49,18 +41,23 @@ def skip_example(example, board): token = token.strip("\"") _, opt_mcu = token.split("=") mcu = opt_mcu[len("OPT_MCU_"):] - break if "esp32s2" in token: mcu = "ESP32S2" - break if "esp32s3" in token: mcu = "ESP32S3" + if mcu != "NONE": break # Skip all OPT_MCU_NONE these are WIP port if mcu == "NONE": return True + max3421_enabled = False + for line in mk_contents.splitlines(): + if "MAX3421_HOST=1" in line or 'MAX3421_HOST 1' in line: + max3421_enabled = True + break + skip_file = ex_dir / "skip.txt" only_file = ex_dir / "only.txt" @@ -74,6 +71,7 @@ def skip_example(example, board): if only_file.exists(): onlys = only_file.read_text().split() if not ("mcu:" + mcu in onlys or + ("mcu:MAX3421" in onlys and max3421_enabled) or "board:" + board in onlys or "family:" + family in onlys): return True -- cgit v1.3.1 From fa44923de1d43e4fd429563e609d59fe19f92107 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 30 Sep 2024 22:13:30 +0700 Subject: skip some examples for mcxa15 --- examples/device/audio_4_channel_mic_freertos/skip.txt | 1 + examples/device/audio_test_freertos/skip.txt | 1 + examples/device/cdc_msc_freertos/skip.txt | 1 + examples/device/hid_composite_freertos/skip.txt | 1 + examples/device/net_lwip_webserver/skip.txt | 1 + examples/device/video_capture/skip.txt | 1 + examples/device/video_capture_2ch/skip.txt | 1 + 7 files changed, 7 insertions(+) diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt index 012ca4e74..30cd46e7e 100644 --- a/examples/device/audio_4_channel_mic_freertos/skip.txt +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -4,6 +4,7 @@ mcu:CH32V307 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 +mcu:MCXA15 mcu:MKL25ZXX mcu:MSP430x5xx mcu:RP2040 diff --git a/examples/device/audio_test_freertos/skip.txt b/examples/device/audio_test_freertos/skip.txt index c13667f56..650bf355b 100644 --- a/examples/device/audio_test_freertos/skip.txt +++ b/examples/device/audio_test_freertos/skip.txt @@ -4,6 +4,7 @@ mcu:CH32V307 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 +mcu:MCXA15 mcu:MKL25ZXX mcu:MSP430x5xx mcu:RP2040 diff --git a/examples/device/cdc_msc_freertos/skip.txt b/examples/device/cdc_msc_freertos/skip.txt index 75a79aff4..b73a6d8dd 100644 --- a/examples/device/cdc_msc_freertos/skip.txt +++ b/examples/device/cdc_msc_freertos/skip.txt @@ -4,6 +4,7 @@ mcu:CH32V307 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 +mcu:MCXA15 mcu:MKL25ZXX mcu:MSP430x5xx mcu:RP2040 diff --git a/examples/device/hid_composite_freertos/skip.txt b/examples/device/hid_composite_freertos/skip.txt index c13667f56..650bf355b 100644 --- a/examples/device/hid_composite_freertos/skip.txt +++ b/examples/device/hid_composite_freertos/skip.txt @@ -4,6 +4,7 @@ mcu:CH32V307 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 +mcu:MCXA15 mcu:MKL25ZXX mcu:MSP430x5xx mcu:RP2040 diff --git a/examples/device/net_lwip_webserver/skip.txt b/examples/device/net_lwip_webserver/skip.txt index 85c450e82..5ebe71612 100644 --- a/examples/device/net_lwip_webserver/skip.txt +++ b/examples/device/net_lwip_webserver/skip.txt @@ -3,6 +3,7 @@ mcu:CH32V20X mcu:LPC11UXX mcu:LPC13XX mcu:LPC15XX +mcu:MCXA15 mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 diff --git a/examples/device/video_capture/skip.txt b/examples/device/video_capture/skip.txt index cb0c7d2e6..50302c544 100644 --- a/examples/device/video_capture/skip.txt +++ b/examples/device/video_capture/skip.txt @@ -1,5 +1,6 @@ mcu:CH32V103 mcu:CH32V20X +mcu:MCXA15 mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 diff --git a/examples/device/video_capture_2ch/skip.txt b/examples/device/video_capture_2ch/skip.txt index af3b0de04..0f6508226 100644 --- a/examples/device/video_capture_2ch/skip.txt +++ b/examples/device/video_capture_2ch/skip.txt @@ -6,6 +6,7 @@ mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:STM32L0 +mcu:MCXA15 family:espressif board:curiosity_nano board:kuiic -- cgit v1.3.1 From d6c8719bcb1607e6b0c668f15655de483e15f02e Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 30 Sep 2024 23:16:53 +0700 Subject: temporarily update hil_test.py to have dual/host_info_to_device_cdc optional for pico/pico2 since it does not seem to be stable enough --- test/hil/hil_test.py | 13 +++++++++---- test/hil/tinyusb.json | 1 - 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 2d14220c5..f152b1aa9 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -240,8 +240,13 @@ def test_dual_host_info_to_device_cdc(board): print(f'\r\n {l} ', end='') enum_dev_sn.append(f'{vid_pid_sn.group(1)}_{vid_pid_sn.group(2)}_{vid_pid_sn.group(3)}') - assert(set(declared_devs) == set(enum_dev_sn)), \ - f'Enumerated devices {enum_dev_sn} not match with declared {declared_devs}' + if set(declared_devs) != set(enum_dev_sn): + # for pico/pico2 make this test optional + failed_msg = f'Enumerated devices {enum_dev_sn} not match with declared {declared_devs}' + if 'raspberry_pi_pico' in board['name']: + print(f'\r\n {failed_msg} ', end='') + else: + assert False, failed_msg return 0 @@ -405,6 +410,8 @@ def test_board(board): if 'tests' in board: board_tests = board['tests'] + if 'dual_attached' in board_tests: + test_list += dual_tests if 'only' in board_tests: test_list = board_tests['only'] if 'skip' in board_tests: @@ -412,8 +419,6 @@ def test_board(board): if skip in test_list: test_list.remove(skip) print(f'{name:25} {skip:30} ... Skip') - if 'dual_attached' in board_tests: - test_list += dual_tests # board_test is added last to disable board's usb test_list.append('device/board_test') diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json index fcd004c6d..066dc5876 100644 --- a/test/hil/tinyusb.json +++ b/test/hil/tinyusb.json @@ -59,7 +59,6 @@ "flasher_sn": "E6633861A3978538", "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2350.cfg -c \"adapter speed 5000\"", "tests": { - "skip": ["dual/host_info_to_device_cdc"], "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "533D004242"}] } }, -- cgit v1.3.1 From 53989a99f60e755094f146e936b49b0ef24e6ec0 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 28 Sep 2024 11:24:35 +0200 Subject: Fix vendor class reset. --- src/class/vendor/vendor_device.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 15829991a..ca04d9a01 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -185,6 +185,8 @@ void vendord_reset(uint8_t rhport) { tu_memclr(p_itf, ITF_MEM_RESET_SIZE); tu_edpt_stream_clear(&p_itf->rx.stream); tu_edpt_stream_clear(&p_itf->tx.stream); + tu_edpt_stream_close(&p_itf->rx.stream); + tu_edpt_stream_close(&p_itf->tx.stream); } } -- cgit v1.3.1 From 3fa7da95bd2a7189020ba6fe2d6aa17577f83abd Mon Sep 17 00:00:00 2001 From: "Haefner, Martin" Date: Tue, 1 Oct 2024 15:24:11 +0200 Subject: support stm32U0 device --- src/common/tusb_mcu.h | 5 +++++ src/portable/st/stm32_fsdev/fsdev_stm32.h | 26 ++++++++++++++++++++++++++ src/portable/synopsys/dwc2/dwc2_stm32.h | 7 +++++++ src/tusb_option.h | 1 + 4 files changed, 39 insertions(+) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 0a4462a0a..87f47e732 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -293,6 +293,11 @@ #define TUP_USBIP_FSDEV_STM32 #define TUP_DCD_ENDPOINT_MAX 8 +#elif TU_CHECK_MCU(OPT_MCU_STM32U0) + #define TUP_USBIP_FSDEV + #define TUP_USBIP_FSDEV_STM32 + #define TUP_DCD_ENDPOINT_MAX 8 + //--------------------------------------------------------------------+ // Sony //--------------------------------------------------------------------+ diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index 99fe8d55f..03ea4c67e 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -170,6 +170,30 @@ #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY #define USB_CNTR_FSUSP USB_CNTR_SUSPEN +#elif CFG_TUSB_MCU == OPT_MCU_STM32U0 + #include "stm32u0xx.h" + #define FSDEV_PMA_SIZE (2048u) + #define USB USB_DRD_FS + + #define USB_EP_CTR_RX USB_EP_VTRX + #define USB_EP_CTR_TX USB_EP_VTTX + #define USB_EP_T_FIELD USB_CHEP_UTYPE + #define USB_EPREG_MASK USB_CHEP_REG_MASK + #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK + #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK + #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 + #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 + #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 + #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 + #define USB_EPRX_STAT USB_CH_RX_VALID + #define USB_EPKIND_MASK USB_EP_KIND_MASK + #define USB_CNTR_FRES USB_CNTR_USBRST + #define USB_CNTR_RESUME USB_CNTR_L2RES + #define USB_ISTR_EP_ID USB_ISTR_IDN + #define USB_EPADDR_FIELD USB_CHEP_ADDR + #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY + #define USB_CNTR_FSUSP USB_CNTR_SUSPEN + #else #error You are using an untested or unimplemented STM32 variant. Please update the driver. // This includes U0 @@ -249,6 +273,8 @@ static const IRQn_Type fsdev_irq[] = { USB_LP_IRQn, #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 USB_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32U0 + USB_DRD_FS_IRQn, #else #error Unknown arch in USB driver #endif diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 3237a50f6..906538779 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -94,6 +94,13 @@ extern "C" { #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 #endif + +#elif CFG_TUSB_MCU == OPT_MCU_STM32U0 + #include "stm32u0xx.h" + #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE + #define EP_MAX_FS 6 + #define EP_FIFO_SIZE_FS 1280 + #else #error "Unsupported MCUs" #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index fb0209023..690859120 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -91,6 +91,7 @@ #define OPT_MCU_STM32U5 313 ///< ST U5 #define OPT_MCU_STM32L5 314 ///< ST L5 #define OPT_MCU_STM32H5 315 ///< ST H5 +#define OPT_MCU_STM32U0 316 ///< ST U0 // Sony #define OPT_MCU_CXD56 400 ///< SONY CXD56 -- cgit v1.3.1 From 1b295de9adbe8eb42f1590ce6b478af5c23e5f8b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 15:01:03 +0700 Subject: add hil_ci_set_matrix.py, starting to support hil with additional build flags --- .github/workflows/build.yml | 6 ++-- .github/workflows/ci_set_matrix.py | 2 +- .github/workflows/hil_test.yml | 7 ++--- test/hil/hil_ci_set_matrix.py | 42 +++++++++++++++++++++++++ test/hil/hil_test.py | 64 +++++++++++++++++++++----------------- tools/build.py | 39 +++++++++++++++++------ 6 files changed, 113 insertions(+), 47 deletions(-) create mode 100644 test/hil/hil_ci_set_matrix.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 70bb3113f..8d5bcbc67 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -65,7 +65,7 @@ jobs: with: build-system: 'cmake' toolchain: ${{ matrix.toolchain }} - build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} + build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }} one-per-family: ${{ github.event_name == 'push' }} # --------------------------------------- @@ -89,7 +89,7 @@ jobs: with: build-system: 'make' toolchain: ${{ matrix.toolchain }} - build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} + build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }} one-per-family: true # --------------------------------------- @@ -117,7 +117,7 @@ jobs: needs: set-matrix runs-on: [self-hosted, Linux, X64, hifiphile] env: - BUILD_ARGS: ${{ join(fromJSON(needs.set-matrix.outputs.json)['arm-iar'].family, ' ') }} + BUILD_ARGS: ${{ join(fromJSON(needs.set-matrix.outputs.json)['arm-iar'], ' ') }} steps: - name: Clean workspace run: | diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 8974037e4..7cc749d48 100644 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -62,7 +62,7 @@ def set_matrix_json(): hfp_boards = [f"-b{board['name']}" for board in hfp_data['boards']] filtered_families = filtered_families + hfp_boards - matrix[toolchain] = {"family": filtered_families} + matrix[toolchain] = filtered_families print(json.dumps(matrix)) diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index 6ece44922..7c94fdf6a 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -32,10 +32,7 @@ jobs: - name: Generate matrix json id: set-matrix-json run: | - MATRIX_ARMGCC=$(jq -c '{ "arm-gcc": { "family": [.boards[] | select(.flasher != "esptool" and .flasher != "openocd_wch") | "-b \(.name)"] } }' "${{ env.HIL_JSON }}") - MATRIX_ESP=$(jq -c '{ "esp-idf": { "family": [.boards[] | select(.flasher == "esptool") | "-b \(.name)"] } }' "${{ env.HIL_JSON }}") - MATRIX_RISCV=$(jq -c '{ "riscv-gcc": { "family": [.boards[] | select(.flasher == "openocd_wch") | "-b \(.name)"] } }' "${{ env.HIL_JSON }}") - MATRIX_JSON=$(jq -nc --argjson arm "$MATRIX_ARMGCC" --argjson esp "$MATRIX_ESP" --argjson riscv "$MATRIX_RISCV" '$arm + $esp + $riscv') + MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py) echo "matrix=$MATRIX_JSON" echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT @@ -55,7 +52,7 @@ jobs: with: build-system: 'cmake' toolchain: ${{ matrix.toolchain }} - build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} + build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }} one-per-family: true upload-artifacts: true diff --git a/test/hil/hil_ci_set_matrix.py b/test/hil/hil_ci_set_matrix.py new file mode 100644 index 000000000..56952eab3 --- /dev/null +++ b/test/hil/hil_ci_set_matrix.py @@ -0,0 +1,42 @@ +import argparse +import json +import os + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('config_file', help='Configuration JSON file') + args = parser.parse_args() + + config_file = args.config_file + + # if config file is not found, try to find it in the same directory as this script + if not os.path.exists(config_file): + config_file = os.path.join(os.path.dirname(__file__), config_file) + with open(config_file) as f: + config = json.load(f) + + matrix = { + 'arm-gcc': [], + 'esp-idf': [] + } + for board in config['boards']: + name = board['name'] + if board['flasher'] == 'esptool': + toolchain = 'esp-idf' + else: + toolchain = 'arm-gcc' + + if 'build_flags_on' in board: + for f in board['build_flags_on']: + if f == '': + matrix[toolchain].append(f'-b {name}') + else: + matrix[toolchain].append(f'-b {name}-{f.replace(" ", "_")}') + else: + matrix[toolchain].append(f'-b {name}') + + print(json.dumps(matrix)) + + +if __name__ == '__main__': + main() diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index cb885aeb5..eaa9dd3bd 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -424,37 +424,45 @@ def test_board(board): test_list.append('device/board_test') err_count = 0 - for test in test_list: - fw_dir = f'cmake-build/cmake-build-{name}/{test}' - if not os.path.exists(fw_dir): - fw_dir = f'examples/cmake-build-{name}/{test}' - fw_name = f'{fw_dir}/{os.path.basename(test)}' - print(f'{name:25} {test:30} ... ', end='') - - if not os.path.exists(fw_dir): - print('Skip (no binary)') - continue - - # flash firmware. It may fail randomly, retry a few times - for i in range(3): - ret = globals()[f'flash_{flasher}'](board, fw_name) + flags_opt_list = [""] + if 'build_flags_on' in board: + flags_opt_list = board['build_flags_on'] + + for flags_opt in flags_opt_list: + flags_opt_str = "" + if flags_opt != "": + flags_opt_str = '-' + flags_opt.replace(' ', '-') + for test in test_list: + fw_dir = f'cmake-build/cmake-build-{name}{flags_opt_str}/{test}' + if not os.path.exists(fw_dir): + fw_dir = f'examples/cmake-build-{name}{flags_opt_str}/{test}' + fw_name = f'{fw_dir}/{os.path.basename(test)}' + print(f'{name+flags_opt_str:40} {test:30} ... ', end='') + + if not os.path.exists(fw_dir): + print('Skip (no binary)') + continue + + # flash firmware. It may fail randomly, retry a few times + for i in range(3): + ret = globals()[f'flash_{flasher}'](board, fw_name) + if ret.returncode == 0: + break + else: + print(f'Flashing failed, retry {i+1}') + time.sleep(1) + if ret.returncode == 0: - break + try: + ret = globals()[f'test_{test.replace("/", "_")}'](board) + print('OK') + except Exception as e: + err_count += 1 + print(STATUS_FAILED) + print(f' {e}') else: - print(f'Flashing failed, retry {i+1}') - time.sleep(1) - - if ret.returncode == 0: - try: - ret = globals()[f'test_{test.replace("/", "_")}'](board) - print('OK') - except Exception as e: err_count += 1 - print(STATUS_FAILED) - print(f' {e}') - else: - err_count += 1 - print(f'Flash {STATUS_FAILED}') + print(f'Flash {STATUS_FAILED}') return err_count diff --git a/tools/build.py b/tools/build.py index 44ac251de..3a771ed6b 100644 --- a/tools/build.py +++ b/tools/build.py @@ -21,6 +21,7 @@ build_format = '| {:30} | {:40} | {:16} | {:5} |' build_separator = '-' * 95 build_status = [STATUS_OK, STATUS_FAILED, STATUS_SKIPPED] +verbose = False # ----------------------------- # Helper @@ -38,6 +39,9 @@ def run_cmd(cmd): else: print(title) print(r.stdout.decode("utf-8")) + elif verbose: + print(cmd) + print(r.stdout.decode("utf-8")) return r @@ -75,10 +79,17 @@ def print_build_result(board, example, status, duration): # ----------------------------- # CMake # ----------------------------- -def cmake_board(board, toolchain): +def cmake_board(board, toolchain, build_flags_on): ret = [0, 0, 0] start_time = time.monotonic() - build_dir = f"cmake-build/cmake-build-{board}" + + build_dir = f'cmake-build/cmake-build-{board}' + build_flags = '' + if len(build_flags_on) > 0: + build_flags = ' '.join(f'-D{flag}=1' for flag in build_flags_on) + build_flags = f'-DCFLAGS_CLI="{build_flags}"' + build_dir += '-' + '-'.join(build_flags_on) + family = find_family(board) if family == 'espressif': # for espressif, we have to build example individually @@ -87,12 +98,14 @@ def cmake_board(board, toolchain): if build_utils.skip_example(example, board): ret[2] += 1 else: - rcmd = run_cmd(f'cmake examples/{example} -B {build_dir}/{example} -G "Ninja" -DBOARD={board}') + rcmd = run_cmd(f'cmake examples/{example} -B {build_dir}/{example} -G "Ninja" ' + f'-DBOARD={board} {build_flags}') if rcmd.returncode == 0: rcmd = run_cmd(f'cmake --build {build_dir}/{example}') ret[0 if rcmd.returncode == 0 else 1] += 1 else: - rcmd = run_cmd(f'cmake examples -B {build_dir} -G "Ninja" -DBOARD={board} -DCMAKE_BUILD_TYPE=MinSizeRel -DTOOLCHAIN={toolchain}') + rcmd = run_cmd(f'cmake examples -B {build_dir} -G "Ninja" -DBOARD={board} -DCMAKE_BUILD_TYPE=MinSizeRel ' + f'-DTOOLCHAIN={toolchain} {build_flags}') if rcmd.returncode == 0: rcmd = run_cmd(f"cmake --build {build_dir}") ret[0 if rcmd.returncode == 0 else 1] += 1 @@ -144,12 +157,12 @@ def make_board(board, toolchain): # ----------------------------- # Build Family # ----------------------------- -def build_boards_list(boards, toolchain, build_system): +def build_boards_list(boards, toolchain, build_system, build_flags_on): ret = [0, 0, 0] for b in boards: r = [0, 0, 0] if build_system == 'cmake': - r = cmake_board(b, toolchain) + r = cmake_board(b, toolchain, build_flags_on) elif build_system == 'make': r = make_board(b, toolchain) ret[0] += r[0] @@ -158,7 +171,7 @@ def build_boards_list(boards, toolchain, build_system): return ret -def build_family(family, toolchain, build_system, one_per_family, boards): +def build_family(family, toolchain, build_system, build_flags_on, one_per_family, boards): all_boards = [] for entry in os.scandir(f"hw/bsp/{family}/boards"): if entry.is_dir() and entry.name != 'pico_sdk': @@ -174,7 +187,7 @@ def build_family(family, toolchain, build_system, one_per_family, boards): return ret all_boards = [random.choice(all_boards)] - ret = build_boards_list(all_boards, toolchain, build_system) + ret = build_boards_list(all_boards, toolchain, build_system, build_flags_on) return ret @@ -182,19 +195,25 @@ def build_family(family, toolchain, build_system, one_per_family, boards): # Main # ----------------------------- def main(): + global verbose + parser = argparse.ArgumentParser() parser.add_argument('families', nargs='*', default=[], help='Families to build') parser.add_argument('-b', '--board', action='append', default=[], help='Boards to build') parser.add_argument('-t', '--toolchain', default='gcc', help='Toolchain to use, default is gcc') parser.add_argument('-s', '--build-system', default='cmake', help='Build system to use, default is cmake') + parser.add_argument('-f1', '--build-flags-on', action='append', default=[], help='Build flag to pass to build system') parser.add_argument('-1', '--one-per-family', action='store_true', default=False, help='Build only one random board inside a family') + parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output') args = parser.parse_args() families = args.families boards = args.board toolchain = args.toolchain build_system = args.build_system + build_flags_on = args.build_flags_on one_per_family = args.one_per_family + verbose = args.verbose if len(families) == 0 and len(boards) == 0: print("Please specify families or board to build") @@ -217,13 +236,13 @@ def main(): # succeeded, failed, skipped for f in all_families: - r = build_family(f, toolchain, build_system, one_per_family, boards) + r = build_family(f, toolchain, build_system, build_flags_on, one_per_family, boards) result[0] += r[0] result[1] += r[1] result[2] += r[2] # build boards - r = build_boards_list(boards, toolchain, build_system) + r = build_boards_list(boards, toolchain, build_system, build_flags_on) result[0] += r[0] result[1] += r[1] result[2] += r[2] -- cgit v1.3.1 From 5a5dbfc8c65273cf97fe5f5382d1d69de5dcd66d Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 15:05:02 +0700 Subject: fix missing json --- .github/workflows/hil_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index 7c94fdf6a..579e935ac 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -32,7 +32,7 @@ jobs: - name: Generate matrix json id: set-matrix-json run: | - MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py) + MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py ${{ env.HIL_JSON }}) echo "matrix=$MATRIX_JSON" echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT -- cgit v1.3.1 From 072a80d088c5c74a97b9ac525c6c7f7c53627ccb Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 16:02:46 +0700 Subject: hil test both slave and dma for dwc2 esp32s3 --- .github/workflows/hil_test.yml | 2 +- test/hil/hil_ci_set_matrix.py | 3 ++- test/hil/tinyusb.json | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index 579e935ac..d5f4e4fdd 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -58,7 +58,7 @@ jobs: # --------------------------------------- # Hardware in the loop (HIL) - # self-hosted running on an VM. For attached hardware checkout test/hil/tinyusb.json + # self-hosted running on an VM. For attached hardware checkout HIL_JSON # --------------------------------------- hil-tinyusb: if: github.repository_owner == 'hathach' diff --git a/test/hil/hil_ci_set_matrix.py b/test/hil/hil_ci_set_matrix.py index 56952eab3..d1329f035 100644 --- a/test/hil/hil_ci_set_matrix.py +++ b/test/hil/hil_ci_set_matrix.py @@ -2,6 +2,7 @@ import argparse import json import os + def main(): parser = argparse.ArgumentParser() parser.add_argument('config_file', help='Configuration JSON file') @@ -31,7 +32,7 @@ def main(): if f == '': matrix[toolchain].append(f'-b {name}') else: - matrix[toolchain].append(f'-b {name}-{f.replace(" ", "_")}') + matrix[toolchain].append(f'-b {name} -f1 {f.replace(" ", " -f1 ")}') else: matrix[toolchain].append(f'-b {name}') diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json index 066dc5876..7627e7482 100644 --- a/test/hil/tinyusb.json +++ b/test/hil/tinyusb.json @@ -79,6 +79,7 @@ { "name": "espressif_s3_devkitm", "uid": "84F703C084E4", + "build_flags_on": ["", "CFG_TUD_DWC2_DMA"], "tests": { "only": ["device/cdc_msc_freertos", "device/hid_composite_freertos"] }, -- cgit v1.3.1 From 06347661de26fd2e680a3a9d760677c056d451b5 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 16:09:43 +0700 Subject: accept and ignore -f1 option --- tools/get_deps.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/get_deps.py b/tools/get_deps.py index 06da54b41..5946d7def 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -251,6 +251,7 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument('families', nargs='*', default=[], help='Families to fetch') parser.add_argument('-b', '--board', action='append', default=[], help='Boards to fetch') + parser.add_argument('-f1', '--build-flags-on', action='append', default=[], help='Have no effect') parser.add_argument('--print', action='store_true', help='Print commit hash only') args = parser.parse_args() -- cgit v1.3.1 From 7cdab1c94b2a218928691dbca8cb9290bb31ecc9 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 16:33:58 +0700 Subject: enable dma hil test with hfp.json --- test/hil/hfp.json | 1 + test/hil/hil_ci_set_matrix.py | 4 ++-- test/hil/tinyusb.json | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/test/hil/hfp.json b/test/hil/hfp.json index e79a3cfc9..386d9816b 100644 --- a/test/hil/hfp.json +++ b/test/hil/hfp.json @@ -10,6 +10,7 @@ { "name": "stm32f746disco", "uid": "210041000C51343237303334", + "build_flags_on": ["", "CFG_TUD_DWC2_DMA"], "flasher": "jlink", "flasher_sn": "770935966", "flasher_args": "-device STM32F746NG" diff --git a/test/hil/hil_ci_set_matrix.py b/test/hil/hil_ci_set_matrix.py index d1329f035..192174e16 100644 --- a/test/hil/hil_ci_set_matrix.py +++ b/test/hil/hil_ci_set_matrix.py @@ -27,8 +27,8 @@ def main(): else: toolchain = 'arm-gcc' - if 'build_flags_on' in board: - for f in board['build_flags_on']: + if 'build' in board and 'flags_on' in board['build']: + for f in board['build']['flags_on']: if f == '': matrix[toolchain].append(f'-b {name}') else: diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json index 7627e7482..1eaa08207 100644 --- a/test/hil/tinyusb.json +++ b/test/hil/tinyusb.json @@ -79,7 +79,9 @@ { "name": "espressif_s3_devkitm", "uid": "84F703C084E4", - "build_flags_on": ["", "CFG_TUD_DWC2_DMA"], + "build" : { + "flags_on": ["", "CFG_TUD_DWC2_DMA"] + }, "tests": { "only": ["device/cdc_msc_freertos", "device/hid_composite_freertos"] }, -- cgit v1.3.1 From 790a10728712aa0979185f4df722a471b799eada Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 17:05:45 +0700 Subject: revert hfp dma for now, due to ci build matrix --- test/hil/hfp.json | 1 - 1 file changed, 1 deletion(-) diff --git a/test/hil/hfp.json b/test/hil/hfp.json index 386d9816b..e79a3cfc9 100644 --- a/test/hil/hfp.json +++ b/test/hil/hfp.json @@ -10,7 +10,6 @@ { "name": "stm32f746disco", "uid": "210041000C51343237303334", - "build_flags_on": ["", "CFG_TUD_DWC2_DMA"], "flasher": "jlink", "flasher_sn": "770935966", "flasher_args": "-device STM32F746NG" -- cgit v1.3.1 From 0abd6474d95055bcaafcd2c794ae726ffdee6f9f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 17:10:13 +0700 Subject: fix circleci set-matrix --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 83f554916..28afafb00 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,7 +34,7 @@ jobs: e_arr=($e) build_system="${e_arr[0]}" toolchain="${e_arr[1]}" - FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\".family") + FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\"") echo "FAMILY_${toolchain}=$FAMILY" # FAMILY_LARGE = FAMILY - RESOURCE_LARGE -- cgit v1.3.1 From 73f7ce7103c0d002d787abfc1ae73d1f9e087f0b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 17:26:14 +0700 Subject: U0 does not have dwc2 controller --- src/portable/synopsys/dwc2/dwc2_stm32.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index e9f6bdd91..395b6d870 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -94,13 +94,6 @@ extern "C" { #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 #endif - -#elif CFG_TUSB_MCU == OPT_MCU_STM32U0 - #include "stm32u0xx.h" - #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE - #define EP_MAX_FS 6 - #define EP_FIFO_SIZE_FS 1280 - #else #error "Unsupported MCUs" #endif -- cgit v1.3.1 From 31c123aa32f643c18ca14ff9e348e4c2d66e3963 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 17:38:57 +0700 Subject: update new json change --- .github/workflows/hil_test.yml | 4 +++- test/hil/hil_test.py | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml index d5f4e4fdd..c6e7f33b0 100644 --- a/.github/workflows/hil_test.yml +++ b/.github/workflows/hil_test.yml @@ -83,4 +83,6 @@ jobs: merge-multiple: true - name: Test on actual hardware - run: python3 test/hil/hil_test.py ${{ env.HIL_JSON }} + run: | + ls cmake-build/ + python3 test/hil/hil_test.py ${{ env.HIL_JSON }} diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index eaa9dd3bd..50f72b30f 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -424,20 +424,20 @@ def test_board(board): test_list.append('device/board_test') err_count = 0 - flags_opt_list = [""] - if 'build_flags_on' in board: - flags_opt_list = board['build_flags_on'] - - for flags_opt in flags_opt_list: - flags_opt_str = "" - if flags_opt != "": - flags_opt_str = '-' + flags_opt.replace(' ', '-') + flags_on_list = [""] + if 'build' in board and 'flags_on' in board['build']: + flags_on_list = board['build']['flags_on'] + + for f1 in flags_on_list: + f1_str = "" + if f1 != "": + f1_str = '-' + f1.replace(' ', '-') for test in test_list: - fw_dir = f'cmake-build/cmake-build-{name}{flags_opt_str}/{test}' + fw_dir = f'cmake-build/cmake-build-{name}{f1_str}/{test}' if not os.path.exists(fw_dir): - fw_dir = f'examples/cmake-build-{name}{flags_opt_str}/{test}' + fw_dir = f'examples/cmake-build-{name}{f1_str}/{test}' fw_name = f'{fw_dir}/{os.path.basename(test)}' - print(f'{name+flags_opt_str:40} {test:30} ... ', end='') + print(f'{name+f1_str:40} {test:30} ... ', end='') if not os.path.exists(fw_dir): print('Skip (no binary)') -- cgit v1.3.1 From cb5e273e9a9bde61970101191366b3845007eff9 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 22:12:38 +0700 Subject: enhance dwc2 markdown with field mapping --- src/portable/synopsys/dwc2/dwc2_info.md | 116 +++++++++++++------------- src/portable/synopsys/dwc2/dwc2_info.py | 140 +++++++++++++++++++------------- 2 files changed, 140 insertions(+), 116 deletions(-) diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index 462b5856a..cd8a57ec3 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -1,58 +1,58 @@ -| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | ESP32-P4 | STM32F 407/411/429 FS | STM32F 407/429 HS | STM32F 412/767 FS | STM32F723 FS | STM32F723 HS | STM32H743 HS | STM32L476 FS | STM32U5A5 HS | GD32VF103 FS | XMC4500 | -|:---------------------------|:----------------|:-------------|:--------------|:-----------|:------------------------|:--------------------|:--------------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:-----------| -| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | -| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | -| - specs version | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | -| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | -| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | -| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | -| - arch | 2 | 2 | 2 | 2 | 0 | 2 | 0 | 0 | 2 | 2 | 0 | 2 | 0 | 2 | -| - point2point | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | -| - hs_phy_type | 1 | 0 | 0 | 3 | 0 | 2 | 0 | 0 | 3 | 2 | 0 | 1 | 0 | 0 | -| - fs_phy_type | 1 | 1 | 1 | 3 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - num_dev_ep | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | -| - num_host_ch | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 11 | 15 | 0 | 13 | -| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - nptx_q_depth | 2 | 2 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - ptx_q_depth | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | -| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | -| - xfer_size_width | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | -| - packet_size_width | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | -| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - i2c_enable | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | -| - vendor_ctrl_itf | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | -| - optional_feature_removed | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - synch_reset | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - otg_adp_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - battery_charger_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | -| - dfifo_depth | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 952 | 512 | 952 | 0 | 634 | -| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | -| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - enhanced_lpm_support | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - phy_data_width | 0 | 2 | 2 | 2 | 2 | 0 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 2 | -| - ctrl_ep_num | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - num_dev_in_eps | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | -| - dma_desc_enable | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | -| - dma_desc_dynamic | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | ESP32-P4 | ST F407/411/429 FS | ST F407/429 HS | ST F412/767 FS | ST F723 FS | ST F723 HS | ST F769 | ST H743 HS | ST L476 FS | ST U5A5 HS | GD32VF103 FS | XMC4500 | +|:---------------------------|:----------------|:-------------|:--------------|:-------------|:---------------------|:-----------------|:-----------------|:-------------|:-------------|:-------------|:-------------|:-------------|:-------------|:---------------|:-------------| +| GUID | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | +| GSNPSID | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | +| - specs version | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | +| GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| GHWCFG2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | +| - op_mode | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | +| - arch | DMA internal | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | Slave only | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | DMA internal | +| - p2p (hub support) | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | +| - hs_phy_type | UTMI+ | N/A | N/A | UTMI+/ULPI | N/A | ULPI | N/A | N/A | UTMI+/ULPI | ULPI | ULPI | N/A | UTMI+ | N/A | N/A | +| - fs_phy_type | Dedicated | Dedicated | Dedicated | Shared ULPI | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | N/A | N/A | Dedicated | +| - num_dev_ep | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 | +| - num_host_ch | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 0 | 13 | +| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - nptx_q_depth | 2 | 2 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - ptx_q_depth | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | +| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| GHWCFG3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | +| - xfer_size_width | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | +| - packet_size_width | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | +| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - i2c_enable | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | +| - vendor_ctrl_itf | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | +| - optional_feature_removed | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - synch_reset | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - otg_adp_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - battery_charger_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | +| - dfifo_depth | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 1006 | 952 | 512 | 952 | 0 | 634 | +| GHWCFG4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | +| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - enhanced_lpm_support | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - phy_data_width | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8 bit | 8/16 bit | +| - ctrl_ep_num | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - num_dev_in_eps | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 | +| - dma_desc_enable | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| - dma_desc_dynamic | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index 33997ca19..62437cfde 100755 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -1,24 +1,27 @@ #!/usr/bin/env python3 -import click + import ctypes +import argparse +import click import pandas as pd # hex value for register: guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 # Note: FS is FullSpeed, HS is HighSpeed -dwc2_reg_list = ['guid', 'gsnpsid', 'ghwcfg1', 'ghwcfg2', 'ghwcfg3', 'ghwcfg4'] +dwc2_reg_list = ['GUID', 'GSNPSID', 'GHWCFG1', 'GHWCFG2', 'GHWCFG3', 'GHWCFG4'] dwc2_reg_value = { 'BCM2711 (Pi4)': [0x2708A000, 0x4F54280A, 0, 0x228DDD50, 0xFF000E8, 0x1FF00020], 'EFM32GG FS': [0, 0x4F54330A, 0, 0x228F5910, 0x1F204E8, 0x1BF08030], 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0xC804B5, 0xD3F0A030], 'ESP32-P4': [0, 0x4F54400A, 0, 0x215FFFD0, 0x03805EB5, 0xDFF1A030], - 'STM32F 407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], - 'STM32F 407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], - 'STM32F 412/767 FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'STM32F723 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'STM32F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x3EED2E8, 0x23F00030], - 'STM32H743 HS': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x3B8D2E8, 0xE3F00030], # both HS cores - 'STM32L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'STM32U5A5 HS': [0x5000, 0x4F54411A, 0, 0x228FE052, 0x03B882E8, 0xE2103E30], + 'ST F407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], + 'ST F407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], + 'ST F412/767 FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'ST F723 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'ST F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x3EED2E8, 0x23F00030], + 'ST F769': [0x2100, 0x4F54320A, 0, 0x229FE190, 0x03EED2E8, 0x23F00030], + 'ST H743 HS': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x3B8D2E8, 0xE3F00030], # both HS cores + 'ST L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'ST U5A5 HS': [0x5000, 0x4F54411A, 0, 0x228FE052, 0x03B882E8, 0xE2103E30], 'GD32VF103 FS': [0x1000, 0, 0, 0, 0, 0], 'XMC4500': [0xAEC000, 0x4F54292A, 0, 0x228F5930, 0x27A01E5, 0xDBF08030] } @@ -26,12 +29,12 @@ dwc2_reg_value = { # Combine dwc2_info with dwc2_reg_list # dwc2_info = { # 'BCM2711 (Pi4)': { -# 'guid': 0x2708A000, -# 'gsnpsid': 0x4F54280A, -# 'ghwcfg1': 0, -# 'ghwcfg2': 0x228DDD50, -# 'ghwcfg3': 0xFF000E8, -# 'ghwcfg4': 0x1FF00020 +# 'GUID': 0x2708A000, +# 'GSNPSID': 0x4F54280A, +# 'GHWCFG1': 0, +# 'GHWCFG2': 0x228DDD50, +# 'GHWCFG3': 0xFF000E8, +# 'GHWCFG4': 0x1FF00020 # }, dwc2_info = {key: {field: value for field, value in zip(dwc2_reg_list, values)} for key, values in dwc2_reg_value.items()} @@ -40,7 +43,7 @@ class GHWCFG2(ctypes.LittleEndianStructure): _fields_ = [ ("op_mode", ctypes.c_uint32, 3), ("arch", ctypes.c_uint32, 2), - ("point2point", ctypes.c_uint32, 1), + ("p2p (hub support)", ctypes.c_uint32, 1), ("hs_phy_type", ctypes.c_uint32, 2), ("fs_phy_type", ctypes.c_uint32, 2), ("num_dev_ep", ctypes.c_uint32, 4), @@ -99,63 +102,84 @@ class GHWCFG4(ctypes.LittleEndianStructure): ("dma_desc_dynamic", ctypes.c_uint32, 1) ] +# mapping for specific fields in GHWCFG2 +GHWCFG2_field = { + 'op_mode': { + 0: "HNP SRP", + 1: "SRP", + 2: "noHNP noSRP", + 3: "SRP Device", + 4: "noOTG Device", + 5: "SRP Host", + 6: "noOTG Host" + }, + 'arch': { + 0: "Slave only", + 1: "DMA external", + 2: "DMA internal" + }, + 'hs_phy_type': { + 0: "N/A", + 1: "UTMI+", + 2: "ULPI", + 3: "UTMI+/ULPI" + }, + 'fs_phy_type': { + 0: "N/A", + 1: "Dedicated", + 2: "Shared UTMI+", + 3: "Shared ULPI" + } +} -@click.group() -def cli(): - pass - - -@cli.command() -@click.argument('mcus', nargs=-1) -@click.option('-a', '--all', is_flag=True, help='Print all bit-field values') -def info(mcus, all): - """Print DWC2 register values for given MCU(s)""" - if len(mcus) == 0: - mcus = dwc2_info - - for mcu in mcus: - for entry in dwc2_info: - if mcu.lower() in entry.lower(): - print(f"## {entry}") - for r_name, r_value in dwc2_info[entry].items(): - print(f"{r_name} = 0x{r_value:08X}") - # Print bit-field values - if all and r_name.upper() in globals(): - class_name = globals()[r_name.upper()] - ghwcfg = class_name.from_buffer_copy(r_value.to_bytes(4, byteorder='little')) - for field_name, field_type, _ in class_name._fields_: - print(f" {field_name} = {getattr(ghwcfg, field_name)}") +# mapping for specific fields in GHWCFG4 +GHWCFG4_field = { + 'phy_data_width': { + 0: "8 bit", + 1: "16 bit", + 2: "8/16 bit", + 3: "Reserved" + }, + } + +def main(): + """Render dwc2_info to Markdown table""" + parser = argparse.ArgumentParser() + args = parser.parse_args() -@cli.command() -def render_md(): - """Render dwc2_info to Markdown table""" # Create an empty list to hold the dictionaries - dwc2_info_list = [] + md_table = [] # Iterate over the dwc2_info dictionary and extract fields for device, reg_values in dwc2_info.items(): - entry_dict = {"Device": device} + md_item = {"Device": device} for r_name, r_value in reg_values.items(): - entry_dict[r_name] = f"0x{r_value:08X}" + md_item[r_name] = f"0x{r_value:08X}" - if r_name == 'gsnpsid': + if r_name == 'GSNPSID': # Get dwc2 specs version major = ((r_value >> 8) >> 4) & 0x0F minor = (r_value >> 4) & 0xFF patch = chr((r_value & 0x0F) + ord('a') - 0xA) - entry_dict[f' - specs version'] = f"{major:X}.{minor:02X}{patch}" - elif r_name.upper() in globals(): + md_item[f' - specs version'] = f"{major:X}.{minor:02X}{patch}" + elif r_name in globals(): # Get bit-field values which exist as ctypes structures - class_name = globals()[r_name.upper()] - ghwcfg = class_name.from_buffer_copy(r_value.to_bytes(4, byteorder='little')) - for field_name, field_type, _ in class_name._fields_: - entry_dict[f' - {field_name}'] = getattr(ghwcfg, field_name) + class_hdl = globals()[r_name] + ghwcfg = class_hdl.from_buffer_copy(r_value.to_bytes(4, byteorder='little')) + for field_name, field_type, _ in class_hdl._fields_: + field_value = getattr(ghwcfg, field_name) + if class_hdl == GHWCFG2 and field_name in GHWCFG2_field: + field_value = GHWCFG2_field[field_name].get(field_value, f"Unknown ({field_value})") + if class_hdl == GHWCFG4 and field_name in GHWCFG4_field: + field_value = GHWCFG4_field[field_name].get(field_value, f"Unknown ({field_value})") + + md_item[f' - {field_name}'] = field_value - dwc2_info_list.append(entry_dict) + md_table.append(md_item) # Create a Pandas DataFrame from the list of dictionaries - df = pd.DataFrame(dwc2_info_list).set_index('Device') + df = pd.DataFrame(md_table).set_index('Device') # Transpose the DataFrame to switch rows and columns df = df.T @@ -168,4 +192,4 @@ def render_md(): if __name__ == '__main__': - cli() + main() -- cgit v1.3.1 From b2a98eadabf3b48f3d9316b32444f0b9cfbc2d1f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 22:21:08 +0700 Subject: add stm32f769disco to hil pool --- src/portable/synopsys/dwc2/dcd_dwc2.c | 2 +- test/hil/tinyusb.json | 36 ++++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 4fa869241..210ce1bba 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -637,7 +637,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { static bool check_dwc2(dwc2_regs_t* dwc2) { #if CFG_TUSB_DEBUG >= DWC2_DEBUG // print guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 - // Run 'dwc2_info.py render-md' and check dwc2_info.md for bit-field value and comparison with other ports + // Run 'python dwc2_info.py' and check dwc2_info.md for bit-field value and comparison with other ports volatile uint32_t const* p = (volatile uint32_t const*) &dwc2->guid; TU_LOG1("guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4\r\n"); for (size_t i = 0; i < 5; i++) { diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json index 1eaa08207..2358c3c4f 100644 --- a/test/hil/tinyusb.json +++ b/test/hil/tinyusb.json @@ -1,5 +1,18 @@ { "boards": [ + { + "name": "espressif_s3_devkitm", + "uid": "84F703C084E4", + "build" : { + "flags_on": ["", "CFG_TUD_DWC2_DMA"] + }, + "tests": { + "only": ["device/cdc_msc_freertos", "device/hid_composite_freertos"] + }, + "flasher": "esptool", + "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", + "flasher_args": "-b 1500000" + }, { "name": "feather_nrf52840_express", "uid": "1F0479CD0F764471", @@ -69,25 +82,22 @@ "flasher_sn": "779541626", "flasher_args": "-device stm32f072rb" }, + { + "name": "stm32f769disco", + "uid": "21002F000F51363531383437", + "build" : { + "flags_on": ["", "CFG_TUD_DWC2_DMA"] + }, + "flasher": "jlink", + "flasher_sn": "000778170924", + "flasher_args": "-device stm32f769ni" + }, { "name": "stm32g0b1nucleo", "uid": "4D0038000450434E37343120", "flasher": "openocd", "flasher_sn": "066FFF495087534867063844", "flasher_args": "-f interface/stlink.cfg -f target/stm32g0x.cfg" - }, - { - "name": "espressif_s3_devkitm", - "uid": "84F703C084E4", - "build" : { - "flags_on": ["", "CFG_TUD_DWC2_DMA"] - }, - "tests": { - "only": ["device/cdc_msc_freertos", "device/hid_composite_freertos"] - }, - "flasher": "esptool", - "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", - "flasher_args": "-b 921600" } ], "boards-skip": [ -- cgit v1.3.1 From 599bb0c8227f659b15302dac6a04706c7d3b2a4e Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 22:26:40 +0700 Subject: improving dwc2, merging diep and doep if possible --- .idea/cmake.xml | 62 +++--- hw/bsp/stm32h7/boards/stm32h743eval/board.cmake | 1 + hw/bsp/stm32l4/boards/stm32l476disco/board.cmake | 2 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 230 ++++++++++++----------- src/portable/synopsys/dwc2/dwc2_info.md | 6 +- src/portable/synopsys/dwc2/dwc2_info.py | 6 +- src/portable/synopsys/dwc2/dwc2_type.h | 108 +++++++++-- 7 files changed, 246 insertions(+), 169 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 37cd73c65..d4ad3a748 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -9,49 +9,49 @@ - + - + - + - + - + - + - + @@ -65,19 +65,15 @@ - - - - - - - + + + @@ -86,33 +82,22 @@ - - - - - - - - - - - - - - + + + - + - + @@ -124,22 +109,31 @@ - + + + + + - - + + + + + + + + - diff --git a/hw/bsp/stm32h7/boards/stm32h743eval/board.cmake b/hw/bsp/stm32h7/boards/stm32h743eval/board.cmake index a28aa87bd..6d7a97741 100644 --- a/hw/bsp/stm32h7/boards/stm32h743eval/board.cmake +++ b/hw/bsp/stm32h7/boards/stm32h743eval/board.cmake @@ -1,5 +1,6 @@ set(MCU_VARIANT stm32h743xx) set(JLINK_DEVICE stm32h743xi) +# set(JLINK_OPTION "-USB jtrace") set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${MCU_VARIANT}_flash.ld) diff --git a/hw/bsp/stm32l4/boards/stm32l476disco/board.cmake b/hw/bsp/stm32l4/boards/stm32l476disco/board.cmake index 4ade0a5c9..fd1c931c2 100644 --- a/hw/bsp/stm32l4/boards/stm32l476disco/board.cmake +++ b/hw/bsp/stm32l4/boards/stm32l476disco/board.cmake @@ -1,6 +1,6 @@ set(MCU_VARIANT stm32l476xx) set(JLINK_DEVICE stm32l476vg) - +# set(JLINK_OPTION "-USB 000777632258") set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32L476VGTx_FLASH.ld) function(update_board TARGET) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 210ce1bba..99cf3fdaa 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -327,53 +327,49 @@ static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoin xfer->interval = p_endpoint_desc->bInterval; // USBAEP, EPTYP, SD0PID_SEVNFRM, MPSIZ are the same for IN and OUT endpoints. - uint32_t const dxepctl = (1 << DOEPCTL_USBAEP_Pos) | - (p_endpoint_desc->bmAttributes.xfer << DOEPCTL_EPTYP_Pos) | - (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DOEPCTL_SD0PID_SEVNFRM : 0) | - (xfer->max_size << DOEPCTL_MPSIZ_Pos); - - if (dir == TUSB_DIR_OUT) { - dwc2->epout[epnum].doepctl = dxepctl; - dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); - } else { - dwc2->epin[epnum].diepctl = dxepctl | (epnum << DIEPCTL_TXFNUM_Pos); - dwc2->daintmsk |= TU_BIT(DAINTMSK_IEPM_Pos + epnum); + uint32_t epctl = (1 << DOEPCTL_USBAEP_Pos) | + (p_endpoint_desc->bmAttributes.xfer << DOEPCTL_EPTYP_Pos) | + (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DOEPCTL_SD0PID_SEVNFRM : 0) | + (xfer->max_size << DOEPCTL_MPSIZ_Pos); + if (dir == TUSB_DIR_IN) { + epctl |= (epnum << DIEPCTL_TXFNUM_Pos); } + + dwc2_dep_t* dep = &dwc2->ep[1 - dir][epnum]; + dep->ctl = epctl; + dwc2->daintmsk |= TU_BIT(epnum + DAINT_SHIFT(dir)); } static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) { (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + const uint8_t epnum = tu_edpt_number(ep_addr); + const uint8_t dir = tu_edpt_dir(ep_addr); + dwc2_dep_t* dep = &dwc2->ep[1 - dir][epnum]; if (dir == TUSB_DIR_IN) { - dwc2_epin_t* epin = dwc2->epin; - // Only disable currently enabled non-control endpoint - if ((epnum == 0) || !(epin[epnum].diepctl & DIEPCTL_EPENA)) { - epin[epnum].diepctl |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0); + if ((epnum == 0) || !(dep->diepctl & DIEPCTL_EPENA)) { + dep->diepctl |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0); } else { // Stop transmitting packets and NAK IN xfers. - epin[epnum].diepctl |= DIEPCTL_SNAK; - while ((epin[epnum].diepint & DIEPINT_INEPNE) == 0) {} + dep->diepctl |= DIEPCTL_SNAK; + while ((dep->diepint & DIEPINT_INEPNE) == 0) {} // Disable the endpoint. - epin[epnum].diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0); - while ((epin[epnum].diepint & DIEPINT_EPDISD_Msk) == 0) {} + dep->diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0); + while ((dep->diepint & DIEPINT_EPDISD_Msk) == 0) {} - epin[epnum].diepint = DIEPINT_EPDISD; + dep->diepint = DIEPINT_EPDISD; } // Flush the FIFO, and wait until we have confirmed it cleared. dfifo_flush_tx(dwc2, epnum); } else { - dwc2_epout_t* epout = dwc2->epout; - // Only disable currently enabled non-control endpoint - if ((epnum == 0) || !(epout[epnum].doepctl & DOEPCTL_EPENA)) { - epout[epnum].doepctl |= stall ? DOEPCTL_STALL : 0; + if ((epnum == 0) || !(dep->doepctl & DOEPCTL_EPENA)) { + dep->doepctl |= stall ? DOEPCTL_STALL : 0; } else { // Asserting GONAK is required to STALL an OUT endpoint. // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt @@ -382,11 +378,11 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) { dwc2->dctl |= DCTL_SGONAK; while ((dwc2->gintsts & GINTSTS_BOUTNAKEFF_Msk) == 0) {} - // Ditto here- disable the endpoint. - epout[epnum].doepctl |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0); - while ((epout[epnum].doepint & DOEPINT_EPDISD_Msk) == 0) {} + // Ditto here disable the endpoint. + dep->doepctl |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0); + while ((dep->doepint & DOEPINT_EPDISD_Msk) == 0) {} - epout[epnum].doepint = DOEPINT_EPDISD; + dep->doepint = DOEPINT_EPDISD; // Allow other OUT endpoints to keep receiving. dwc2->dctl |= DCTL_CGONAK; @@ -430,7 +426,7 @@ static void bus_reset(uint8_t rhport) { dfifo_init(rhport); - // Fixed control EP0 size to 64 bytes + // Fixed both control EP0 size to 64 bytes dwc2->epin[0].diepctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos); dwc2->epout[0].doepctl &= ~(0x03 << DOEPCTL_MPSIZ_Pos); @@ -461,33 +457,33 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c } // IN and OUT endpoint xfers are interrupt-driven, we just schedule them here. - if (dir == TUSB_DIR_IN) { - dwc2_epin_t* epin = dwc2->epin; + const uint8_t is_epout = 1 - dir; + dwc2_dep_t* dep = &dwc2->ep[is_epout][epnum]; + if (dir == TUSB_DIR_IN) { // A full IN transfer (multiple packets, possibly) triggers XFRC. - epin[epnum].dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) | + dep->dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) | ((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk); if(dma_enabled(dwc2)) { - epin[epnum].diepdma = (uintptr_t)xfer->buffer; + dep->diepdma = (uintptr_t)xfer->buffer; // For ISO endpoint set correct odd/even bit for next frame. - if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { + if ((dep->diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { // Take odd/even bit from frame counter. uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); - epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); + dep->diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); } - epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; + dep->diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; } else { - - epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; + dep->diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; // For ISO endpoint set correct odd/even bit for next frame. - if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { + if ((dep->diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { // Take odd/even bit from frame counter. uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); - epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); + dep->diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); } // Enable fifo empty interrupt only if there are something to put in the fifo. if (total_bytes != 0) { @@ -495,25 +491,23 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c } } } else { - dwc2_epout_t* epout = dwc2->epout; - // A full OUT transfer (multiple packets, possibly) triggers XFRC. - epout[epnum].doeptsiz &= ~(DOEPTSIZ_PKTCNT_Msk | DOEPTSIZ_XFRSIZ); - epout[epnum].doeptsiz |= (num_packets << DOEPTSIZ_PKTCNT_Pos) | + dep->doeptsiz &= ~(DOEPTSIZ_PKTCNT_Msk | DOEPTSIZ_XFRSIZ); + dep->doeptsiz |= (num_packets << DOEPTSIZ_PKTCNT_Pos) | ((total_bytes << DOEPTSIZ_XFRSIZ_Pos) & DOEPTSIZ_XFRSIZ_Msk); - if ((epout[epnum].doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 && + if ((dep->doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 && XFER_CTL_BASE(epnum, dir)->interval == 1) { // Take odd/even bit from frame counter. uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); - epout[epnum].doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk); + dep->doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk); } if(dma_enabled(dwc2)) { - epout[epnum].doepdma = (uintptr_t)xfer->buffer; + dep->doepdma = (uintptr_t)xfer->buffer; } - epout[epnum].doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK; + dep->doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK; } } @@ -837,17 +831,13 @@ void dcd_edpt_close_all(uint8_t rhport) { dwc2->daintmsk = (1 << DAINTMSK_OEPM_Pos) | (1 << DAINTMSK_IEPM_Pos); for (uint8_t n = 1; n < ep_count; n++) { - // disable OUT endpoint - if (dwc2->epout[n].doepctl & DOEPCTL_EPENA) { - dwc2->epout[n].doepctl |= DOEPCTL_SNAK | DOEPCTL_EPDIS; - } - xfer_status[n][TUSB_DIR_OUT].max_size = 0; - - // disable IN endpoint - if (dwc2->epin[n].diepctl & DIEPCTL_EPENA) { - dwc2->epin[n].diepctl |= DIEPCTL_SNAK | DIEPCTL_EPDIS; + for (uint8_t d = 0; d < 2; d++) { + dwc2_dep_t* dep = &dwc2->ep[d][n]; + if (dep->ctl & EPCTL_EPENA) { + dep->ctl |= EPCTL_SNAK | EPCTL_EPDIS; + } + xfer_status[n][1-d].max_size = 0; } - xfer_status[n][TUSB_DIR_IN].max_size = 0; } dfifo_flush_tx(dwc2, 0x10); // all tx fifo @@ -937,21 +927,14 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); + dwc2_dep_t* dep = &dwc2->ep[1 - dir][epnum]; // Clear stall and reset data toggle - if (dir == TUSB_DIR_IN) { - dwc2->epin[epnum].diepctl &= ~DIEPCTL_STALL; - dwc2->epin[epnum].diepctl |= DIEPCTL_SD0PID_SEVNFRM; - } else { - dwc2->epout[epnum].doepctl &= ~DOEPCTL_STALL; - dwc2->epout[epnum].doepctl |= DOEPCTL_SD0PID_SEVNFRM; - } + dep->ctl &= ~EPCTL_STALL;; + dep->ctl |= EPCTL_SD0PID_SEVNFRM; } //-------------------------------------------------------------------- @@ -963,10 +946,10 @@ static void handle_rxflvl_irq(uint8_t rhport) { volatile uint32_t const* rx_fifo = dwc2->fifo[0]; // Pop control word off FIFO - uint32_t const ctl_word = dwc2->grxstsp; - uint8_t const pktsts = (ctl_word & GRXSTSP_PKTSTS_Msk) >> GRXSTSP_PKTSTS_Pos; - uint8_t const epnum = (ctl_word & GRXSTSP_EPNUM_Msk) >> GRXSTSP_EPNUM_Pos; - uint16_t const bcnt = (ctl_word & GRXSTSP_BCNT_Msk) >> GRXSTSP_BCNT_Pos; + uint32_t const grxstsp = dwc2->grxstsp; + uint8_t const pktsts = (grxstsp & GRXSTSP_PKTSTS_Msk) >> GRXSTSP_PKTSTS_Pos; + uint8_t const epnum = (grxstsp & GRXSTSP_EPNUM_Msk) >> GRXSTSP_EPNUM_Pos; + uint16_t const bcnt = (grxstsp & GRXSTSP_BCNT_Msk) >> GRXSTSP_BCNT_Pos; dwc2_epout_t* epout = &dwc2->epout[epnum]; @@ -1024,20 +1007,16 @@ static void handle_rxflvl_irq(uint8_t rhport) { ep0_pending[TUSB_DIR_OUT] = 0; } } - } break; + } - // Out packet done (Interrupt) case GRXSTS_PKTSTS_OUTDONE: - // Occurred on STM32L47 with dwc2 version 3.10a but not found on other version like 2.80a or 3.30a - // May (or not) be 3.10a specific feature/bug or depending on MCU configuration - // XFRC complete is additionally generated when - // - setup packet is received - // - complete the data stage of control write is complete - // It will be handled in handle_epout_irq() + /* Out packet done (Interrupt) + After this entry is popped from the receive FIFO, the controller asserts a Transfer Completed interrupt on + the specified OUT endpoint which will be handled by handle_epout_irq() */ break; - default: // Invalid + default: TU_BREAKPOINT(); break; } @@ -1049,73 +1028,73 @@ static void handle_epout_irq(uint8_t rhport) { // DAINT for a given EP clears when DOEPINTx is cleared. // OEPINT will be cleared when DAINT's out bits are cleared. - for (uint8_t n = 0; n < ep_count; n++) { - if (dwc2->daint & TU_BIT(DAINT_OEPINT_Pos + n)) { - dwc2_epout_t* epout = &dwc2->epout[n]; - - uint32_t const doepint = epout->doepint; - + for (uint8_t epnum = 0; epnum < ep_count; epnum++) { + if (dwc2->daint & TU_BIT(DAINT_OEPINT_Pos + epnum)) { + dwc2_epout_t* epout = &dwc2->epout[epnum]; + const uint32_t doepint = epout->doepint; TU_ASSERT((epout->doepint & DOEPINT_AHBERR) == 0, ); // OUT XFER complete - if (epout->doepint & DOEPINT_XFRC) { + if (doepint & DOEPINT_XFRC) { epout->doepint = DOEPINT_XFRC; - xfer_ctl_t* xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); + xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); if(dma_enabled(dwc2)) { - if (doepint & DOEPINT_STUP) { + if (doepint & DOEPINT_SETUP) { // STPKTRX is only available for version from 3_00a - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_STPKTRX; + if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_DMA_STPKTRX; } - } else if (doepint & DOEPINT_OTEPSPR) { - epout->doepint = DOEPINT_OTEPSPR; + } else if (doepint & DOEPINT_STSPHSRX) { + epout->doepint = DOEPINT_STSPHSRX; } else { - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_STPKTRX; + if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_DMA_STPKTRX; } else { // EP0 can only handle one packet - if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + if ((epnum == 0) && ep0_pending[TUSB_DIR_OUT]) { // Schedule another packet to be received. - edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); } else { // Fix packet length uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; xfer->total_len -= remain; // this is ZLP, so prepare EP0 for next setup - if(n == 0 && xfer->total_len == 0) { + if(epnum == 0 && xfer->total_len == 0) { dma_setup_prepare(rhport); } - dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true); } } } } else { - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { - epout->doepint = DOEPINT_STPKTRX; + // DMA_STPKTRX should only be set in Buffer DMA Mode. However, STM32L476 (slave-only) with v3.10a + // incorrectly set this along with SETUP bit. This may (or not) be STM32L476 or 3.10a specific bug + if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { + epout->doepint = DOEPINT_DMA_STPKTRX; } else { - if ((doepint & DOEPINT_OTEPSPR) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { - epout->doepint = DOEPINT_OTEPSPR; + if ((doepint & DOEPINT_STSPHSRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { + epout->doepint = DOEPINT_STSPHSRX; } // EP0 can only handle one packet - if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + if ((epnum == 0) && ep0_pending[TUSB_DIR_OUT]) { // Schedule another packet to be received. - edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); } else { - dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true); } } } } // SETUP packet Setup Phase done. - if (doepint & DOEPINT_STUP) { - epout->doepint = DOEPINT_STUP; - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_STPKTRX; + if (doepint & DOEPINT_SETUP) { + epout->doepint = DOEPINT_SETUP; + if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_DMA_STPKTRX; } if(dma_enabled(dwc2) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { dma_setup_prepare(rhport); @@ -1195,6 +1174,29 @@ static void handle_epin_irq(uint8_t rhport) { } } +/* Interrupt Hierarchy + + DxEPMSK.XferComplMsk DxEPINTn.XferCompl + | | + +---------- AND --------+ + | + DAINT.xEPnInt DAINTMSK.xEPnMsk + | | + +---------- AND --------+ + | + GINTSTS.xEPInt GINTMSK.xEPIntMsk + | | + +---------- AND --------+ + | + GAHBCFG.GblIntrMsk + | + IRQn + + Note: when OTG_MULTI_PROC_INTRPT = 1, Device Each endpoint interrupt deachint/deachmsk/diepeachmsk/doepeachmsk + are combined to generate dedicated interrupt line for each endpoint. + */ + + void dcd_int_handler(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); @@ -1276,8 +1278,8 @@ void dcd_int_handler(uint8_t rhport) { // Mask out RXFLVL while reading data from FIFO dwc2->gintmsk &= ~GINTMSK_RXFLVLM; - // Loop until all available packets were handled do { + // Loop until all available packets were handled handle_rxflvl_irq(rhport); } while(dwc2->gintsts & GINTSTS_RXFLVL); diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index cd8a57ec3..5c7e5e688 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -8,13 +8,13 @@ | - op_mode | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | | - arch | DMA internal | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | Slave only | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | DMA internal | | - p2p (hub support) | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | -| - hs_phy_type | UTMI+ | N/A | N/A | UTMI+/ULPI | N/A | ULPI | N/A | N/A | UTMI+/ULPI | ULPI | ULPI | N/A | UTMI+ | N/A | N/A | -| - fs_phy_type | Dedicated | Dedicated | Dedicated | Shared ULPI | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | N/A | N/A | Dedicated | +| - hs_phy_type | UTMI+ | n/a | n/a | UTMI+/ULPI | n/a | ULPI | n/a | n/a | UTMI+/ULPI | ULPI | ULPI | n/a | UTMI+ | n/a | n/a | +| - fs_phy_type | Dedicated | Dedicated | Dedicated | Shared ULPI | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | n/a | n/a | Dedicated | | - num_dev_ep | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 | | - num_host_ch | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 0 | 13 | | - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | | - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - mul_proc_intrpt | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | | - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | - nptx_q_depth | 2 | 2 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | | - ptx_q_depth | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index 62437cfde..ac32eb585 100755 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -50,7 +50,7 @@ class GHWCFG2(ctypes.LittleEndianStructure): ("num_host_ch", ctypes.c_uint32, 4), ("period_channel_support", ctypes.c_uint32, 1), ("enable_dynamic_fifo", ctypes.c_uint32, 1), - ("mul_cpu_int", ctypes.c_uint32, 1), + ("mul_proc_intrpt", ctypes.c_uint32, 1), ("reserved21", ctypes.c_uint32, 1), ("nptx_q_depth", ctypes.c_uint32, 2), ("ptx_q_depth", ctypes.c_uint32, 2), @@ -119,13 +119,13 @@ GHWCFG2_field = { 2: "DMA internal" }, 'hs_phy_type': { - 0: "N/A", + 0: "n/a", 1: "UTMI+", 2: "ULPI", 3: "UTMI+/ULPI" }, 'fs_phy_type': { - 0: "N/A", + 0: "n/a", 1: "Dedicated", 2: "Shared UTMI+", 3: "Shared ULPI" diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index ac88dd24d..d5a51fb09 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -250,7 +250,7 @@ typedef struct TU_ATTR_PACKED { uint32_t num_host_ch : 4; // 14..17 Number of host channel (excluding control) uint32_t period_channel_support : 1; // 18 Support Periodic OUT Host Channel uint32_t enable_dynamic_fifo : 1; // 19 Dynamic FIFO Sizing Enabled - uint32_t mul_cpu_int : 1; // 20 Multi-Processor Interrupt Enabled + uint32_t mul_proc_intrpt : 1; // 20 Multi-Processor Interrupt enabled (OTG_MULTI_PROC_INTRPT) uint32_t reserved21 : 1; // 21 reserved uint32_t nptx_q_depth : 2; // 22..23 Non-periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 uint32_t ptx_q_depth : 2; // 24..25 Host periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 @@ -336,6 +336,32 @@ typedef struct { uint32_t reserved18[2]; // B18..B1C } dwc2_epout_t; +typedef struct { + union { + volatile uint32_t diepctl; + volatile uint32_t doepctl; + volatile uint32_t ctl; + }; + uint32_t rsv04; + union { + volatile uint32_t diepint; + volatile uint32_t doepint; + }; + uint32_t rsv0c; + union { + volatile uint32_t dieptsiz; + volatile uint32_t doeptsiz; + }; + union { + volatile uint32_t diepdma; + volatile uint32_t doepdma; + }; + volatile uint32_t dtxfsts; + uint32_t rsv1c; +}dwc2_dep_t; + +TU_VERIFY_STATIC(sizeof(dwc2_dep_t) == 0x20, "incorrect size"); + //-------------------------------------------------------------------- // CSR Register Map //-------------------------------------------------------------------- @@ -418,16 +444,24 @@ typedef struct { volatile uint32_t dvbuspulse; // 82C Device VBUS Pulsing Time volatile uint32_t dthrctl; // 830 Device threshold Control volatile uint32_t diepempmsk; // 834 Device IN Endpoint FIFO Empty Interrupt Mask + + // Device Each Endpoint (IN/OUT) Interrupt/Mask for generating dedicated EP interrupt line + // require OTG_MULTI_PROC_INTRPT=1 volatile uint32_t deachint; // 838 Device Each Endpoint Interrupt - volatile uint32_t deachmsk; // 83C Device Each Endpoint Interrupt msk + volatile uint32_t deachmsk; // 83C Device Each Endpoint Interrupt mask volatile uint32_t diepeachmsk[16]; // 840..87C Device Each IN Endpoint mask volatile uint32_t doepeachmsk[16]; // 880..8BF Device Each OUT Endpoint mask uint32_t reserved8c0[16]; // 8C0..8FF //------------- Device Endpoint -------------// - dwc2_epin_t epin[16]; // 900..AFF IN Endpoints - dwc2_epout_t epout[16]; // B00..CFF OUT Endpoints - uint32_t reservedd00[64]; // D00..DFF + union { + dwc2_dep_t ep[2][16]; // 0: IN, 1 OUT + struct { + dwc2_epin_t epin[16]; // 900..AFF IN Endpoints + dwc2_epout_t epout[16]; // B00..CFF OUT Endpoints + }; + }; + uint32_t reservedd00[64]; // D00..DFF //------------- Power Clock -------------// volatile uint32_t pcgctl; // E00 Power and Clock Gating Control @@ -1094,6 +1128,8 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define DAINTMSK_OEPM_Msk (0xFFFFUL << DAINTMSK_OEPM_Pos) // 0xFFFF0000 #define DAINTMSK_OEPM DAINTMSK_OEPM_Msk // OUT EP interrupt mask bits +#define DAINT_SHIFT(_dir) ((_dir == TUSB_DIR_IN) ? 0 : 16) + #if 0 /******************** Bit definition for OTG register ********************/ #define CHNUM_Pos (0U) @@ -1803,6 +1839,45 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define DIEPTXF_INEPTXFD_Msk (0xFFFFUL << DIEPTXF_INEPTXFD_Pos) // 0xFFFF0000 #define DIEPTXF_INEPTXFD DIEPTXF_INEPTXFD_Msk // IN endpoint TxFIFO depth + +/******************** Bit definition for Common EPCTL register ********************/ +#define EPCTL_MPSIZ_Pos (0U) +#define EPCTL_MPSIZ_Msk (0x7FFUL << EPCTL_MPSIZ_Pos) // 0x000007FF +#define EPCTL_MPSIZ EPCTL_MPSIZ_Msk // Maximum packet size //Bit 1 +#define EPCTL_USBAEP_Pos (15U) +#define EPCTL_USBAEP_Msk (0x1UL << EPCTL_USBAEP_Pos) // 0x00008000 +#define EPCTL_USBAEP EPCTL_USBAEP_Msk // USB active endpoint +#define EPCTL_NAKSTS_Pos (17U) +#define EPCTL_NAKSTS_Msk (0x1UL << EPCTL_NAKSTS_Pos) // 0x00020000 +#define EPCTL_NAKSTS EPCTL_NAKSTS_Msk // NAK status +#define EPCTL_EPTYP_Pos (18U) +#define EPCTL_EPTYP_Msk (0x3UL << EPCTL_EPTYP_Pos) // 0x000C0000 +#define EPCTL_EPTYP EPCTL_EPTYP_Msk // Endpoint type +#define EPCTL_EPTYP_0 (0x1UL << EPCTL_EPTYP_Pos) // 0x00040000 +#define EPCTL_EPTYP_1 (0x2UL << EPCTL_EPTYP_Pos) // 0x00080000 +#define EPCTL_SNPM EPCTL_SNPM_Msk // Snoop mode +#define EPCTL_STALL_Pos (21U) +#define EPCTL_STALL_Msk (0x1UL << EPCTL_STALL_Pos) // 0x00200000 +#define EPCTL_STALL EPCTL_STALL_Msk // STALL handshake +#define EPCTL_CNAK_Pos (26U) +#define EPCTL_CNAK_Msk (0x1UL << EPCTL_CNAK_Pos) // 0x04000000 +#define EPCTL_CNAK EPCTL_CNAK_Msk // Clear NAK +#define EPCTL_SNAK_Pos (27U) +#define EPCTL_SNAK_Msk (0x1UL << EPCTL_SNAK_Pos) // 0x08000000 +#define EPCTL_SNAK EPCTL_SNAK_Msk // Set NAK +#define EPCTL_SD0PID_SEVNFRM_Pos (28U) +#define EPCTL_SD0PID_SEVNFRM_Msk (0x1UL << EPCTL_SD0PID_SEVNFRM_Pos) // 0x10000000 +#define EPCTL_SD0PID_SEVNFRM EPCTL_SD0PID_SEVNFRM_Msk // Set DATA0 PID +#define EPCTL_SODDFRM_Pos (29U) +#define EPCTL_SODDFRM_Msk (0x1UL << EPCTL_SODDFRM_Pos) // 0x20000000 +#define EPCTL_SODDFRM EPCTL_SODDFRM_Msk // Set odd frame +#define EPCTL_EPDIS_Pos (30U) +#define EPCTL_EPDIS_Msk (0x1UL << EPCTL_EPDIS_Pos) // 0x40000000 +#define EPCTL_EPDIS EPCTL_EPDIS_Msk // Endpoint disable +#define EPCTL_EPENA_Pos (31U) +#define EPCTL_EPENA_Msk (0x1UL << EPCTL_EPENA_Pos) // 0x80000000 +#define EPCTL_EPENA EPCTL_EPENA_Msk // Endpoint enable + /******************** Bit definition for DOEPCTL register ********************/ #define DOEPCTL_MPSIZ_Pos (0U) #define DOEPCTL_MPSIZ_Msk (0x7FFUL << DOEPCTL_MPSIZ_Pos) // 0x000007FF @@ -1853,15 +1928,19 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define DOEPINT_AHBERR_Pos (2U) #define DOEPINT_AHBERR_Msk (0x1UL << DOEPINT_AHBERR_Pos) // 0x00000004 #define DOEPINT_AHBERR DOEPINT_AHBERR_Msk // AHB Error (AHBErr) during an OUT transaction -#define DOEPINT_STUP_Pos (3U) -#define DOEPINT_STUP_Msk (0x1UL << DOEPINT_STUP_Pos) // 0x00000008 -#define DOEPINT_STUP DOEPINT_STUP_Msk // SETUP phase done + +#define DOEPINT_SETUP_Pos (3U) +#define DOEPINT_SETUP_Msk (0x1UL << DOEPINT_SETUP_Pos) // 0x00000008 +#define DOEPINT_SETUP DOEPINT_SETUP_Msk // SETUP phase done + #define DOEPINT_OTEPDIS_Pos (4U) #define DOEPINT_OTEPDIS_Msk (0x1UL << DOEPINT_OTEPDIS_Pos) // 0x00000010 #define DOEPINT_OTEPDIS DOEPINT_OTEPDIS_Msk // OUT token received when endpoint disabled -#define DOEPINT_OTEPSPR_Pos (5U) -#define DOEPINT_OTEPSPR_Msk (0x1UL << DOEPINT_OTEPSPR_Pos) // 0x00000020 -#define DOEPINT_OTEPSPR DOEPINT_OTEPSPR_Msk // Status Phase Received For Control Write + +#define DOEPINT_STSPHSRX_Pos (5U) +#define DOEPINT_STSPHSRX_Msk (0x1UL << DOEPINT_STSPHSRX_Pos) // 0x00000020 +#define DOEPINT_STSPHSRX DOEPINT_STSPHSRX_Msk // Status Phase Received For Control Write + #define DOEPINT_B2BSTUP_Pos (6U) #define DOEPINT_B2BSTUP_Msk (0x1UL << DOEPINT_B2BSTUP_Pos) // 0x00000040 #define DOEPINT_B2BSTUP DOEPINT_B2BSTUP_Msk // Back-to-back SETUP packets received @@ -1874,9 +1953,10 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define DOEPINT_NYET_Pos (14U) #define DOEPINT_NYET_Msk (0x1UL << DOEPINT_NYET_Pos) // 0x00004000 #define DOEPINT_NYET DOEPINT_NYET_Msk // NYET interrupt -#define DOEPINT_STPKTRX_Pos (15U) -#define DOEPINT_STPKTRX_Msk (0x1UL << DOEPINT_STPKTRX_Pos) // 0x00008000 -#define DOEPINT_STPKTRX DOEPINT_STPKTRX_Msk // Setup Packet Received + +#define DOEPINT_DMA_STPKTRX_Pos (15U) +#define DOEPINT_DMA_STPKTRX_Msk (0x1UL << DOEPINT_DMA_STPKTRX_Pos) // 0x00008000 +#define DOEPINT_DMA_STPKTRX DOEPINT_DMA_STPKTRX_Msk // Setup Packet Received in Buffer DMA Mode /******************** Bit definition for DOEPTSIZ register ********************/ #define DOEPTSIZ_XFRSIZ_Pos (0U) -- cgit v1.3.1 From 07c14f30a6d6cfb1758e3496c3ea73275ae4a062 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Oct 2024 12:36:45 +0700 Subject: add f407disco to hil pool --- hw/bsp/stm32h7/boards/stm32h750_weact/board.cmake | 16 ++ hw/bsp/stm32h7/boards/stm32h750_weact/board.h | 132 ++++++++++++++++ hw/bsp/stm32h7/boards/stm32h750_weact/board.mk | 21 +++ .../stm32h750_weact/stm32h750xx_flash_CM7.ld | 170 +++++++++++++++++++++ hw/bsp/stm32h7/boards/stm32h750bdk/board.cmake | 2 +- hw/bsp/stm32h7/boards/stm32h750bdk/board.mk | 2 +- hw/bsp/stm32h7/family.c | 12 +- src/portable/synopsys/dwc2/dwc2_info.md | 116 +++++++------- src/portable/synopsys/dwc2/dwc2_info.py | 23 +-- test/hil/hil_test.py | 2 +- test/hil/tinyusb.json | 24 ++- 11 files changed, 438 insertions(+), 82 deletions(-) create mode 100644 hw/bsp/stm32h7/boards/stm32h750_weact/board.cmake create mode 100644 hw/bsp/stm32h7/boards/stm32h750_weact/board.h create mode 100644 hw/bsp/stm32h7/boards/stm32h750_weact/board.mk create mode 100644 hw/bsp/stm32h7/boards/stm32h750_weact/stm32h750xx_flash_CM7.ld diff --git a/hw/bsp/stm32h7/boards/stm32h750_weact/board.cmake b/hw/bsp/stm32h7/boards/stm32h750_weact/board.cmake new file mode 100644 index 000000000..6303ca462 --- /dev/null +++ b/hw/bsp/stm32h7/boards/stm32h750_weact/board.cmake @@ -0,0 +1,16 @@ +set(MCU_VARIANT stm32h750xx) +set(JLINK_DEVICE stm32h750vb) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${MCU_VARIANT}_flash_CM7.ld) +set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32H750xx + HSE_VALUE=25000000 + CORE_CM7 + # default to PORT 0 + BOARD_TUD_RHPORT=0 + BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + ) +endfunction() diff --git a/hw/bsp/stm32h7/boards/stm32h750_weact/board.h b/hw/bsp/stm32h7/boards/stm32h750_weact/board.h new file mode 100644 index 000000000..d117637a5 --- /dev/null +++ b/hw/bsp/stm32h7/boards/stm32h750_weact/board.h @@ -0,0 +1,132 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PORT GPIOE +#define LED_PIN GPIO_PIN_3 +#define LED_STATE_ON 1 + +// Blue push-button +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +// UART +//#define UART_DEV USART3 +//#define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE +//#define UART_GPIO_PORT GPIOB +//#define UART_GPIO_AF GPIO_AF7_USART3 +//#define UART_TX_PIN GPIO_PIN_10 +//#define UART_RX_PIN GPIO_PIN_11 + +// VBUS Sense detection +#define OTG_FS_VBUS_SENSE 1 +#define OTG_HS_VBUS_SENSE 0 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void SystemClock_Config(void) { + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + + // Supply configuration update enable + HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); + + // Configure the main internal regulator output voltage + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2); + while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} + + // Configure the PLL clock source + __HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE); + + // Initializes the CPU, AHB and APB busses clocks + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 5; + RCC_OscInitStruct.PLL.PLLN = 96; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLR = 2; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + // Initializes the CPU, AHB and APB busses clocks + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 + |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1; + RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1); + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_SPI4 + |RCC_PERIPHCLK_SPI1|RCC_PERIPHCLK_USB + |RCC_PERIPHCLK_QSPI; + PeriphClkInitStruct.PLL3.PLL3M = 10; + PeriphClkInitStruct.PLL3.PLL3N = 96; + PeriphClkInitStruct.PLL3.PLL3P = 5; + PeriphClkInitStruct.PLL3.PLL3Q = 5; + PeriphClkInitStruct.PLL3.PLL3R = 2; + PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_1; + PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE; + PeriphClkInitStruct.PLL3.PLL3FRACN = 0; + PeriphClkInitStruct.QspiClockSelection = RCC_QSPICLKSOURCE_D1HCLK; + PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL; + PeriphClkInitStruct.Spi45ClockSelection = RCC_SPI45CLKSOURCE_D2PCLK1; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + // Enable USB Voltage detector + HAL_PWREx_EnableUSBVoltageDetector(); +} + +static inline void board_stm32h7_post_init(void) { + // For this board does nothing +} + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/hw/bsp/stm32h7/boards/stm32h750_weact/board.mk b/hw/bsp/stm32h7/boards/stm32h750_weact/board.mk new file mode 100644 index 000000000..a50172cb0 --- /dev/null +++ b/hw/bsp/stm32h7/boards/stm32h750_weact/board.mk @@ -0,0 +1,21 @@ +# STM32H745I-DISCO uses OTG_FS +# FIXME: Reset enumerates, un/replug USB plug does not enumerate + +CFLAGS += -DSTM32H750xx -DCORE_CM7 -DHSE_VALUE=25000000 + +# Default is FulSpeed port +PORT ?= 0 + +# GCC +SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32h750xx.s +LD_FILE_GCC = $(BOARD_PATH)/stm32h750xx_flash_CM7.ld + +# IAR +SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32h750xx.s +LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32h750xx_flash.icf + +# For flash-jlink target +JLINK_DEVICE = stm32h750vb + +# flash target using on-board stlink +flash: flash-jlink diff --git a/hw/bsp/stm32h7/boards/stm32h750_weact/stm32h750xx_flash_CM7.ld b/hw/bsp/stm32h7/boards/stm32h750_weact/stm32h750xx_flash_CM7.ld new file mode 100644 index 000000000..30f220a42 --- /dev/null +++ b/hw/bsp/stm32h7/boards/stm32h750_weact/stm32h750xx_flash_CM7.ld @@ -0,0 +1,170 @@ +/* +****************************************************************************** +** + +** File : LinkerScript.ld +** +** +** Abstract : Linker script for STM32H7 series +** 128Kbytes FLASH and 1Mbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed �as is,� without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +** Copyright (c) 2019 STMicroelectronics. +** All rights reserved. +** +** This software component is licensed by ST under BSD 3-Clause license, +** the "License"; You may not use this file except in compliance with the +** License. You may obtain a copy of the License at: +** opensource.org/licenses/BSD-3-Clause +** +**************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 1M +ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32h7/boards/stm32h750bdk/board.cmake b/hw/bsp/stm32h7/boards/stm32h750bdk/board.cmake index 6eff708a8..e87be8255 100644 --- a/hw/bsp/stm32h7/boards/stm32h750bdk/board.cmake +++ b/hw/bsp/stm32h7/boards/stm32h750bdk/board.cmake @@ -1,5 +1,5 @@ set(MCU_VARIANT stm32h750xx) -set(JLINK_DEVICE stm32h750xb_m7) +set(JLINK_DEVICE stm32h750xb) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${MCU_VARIANT}_flash_CM7.ld) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) diff --git a/hw/bsp/stm32h7/boards/stm32h750bdk/board.mk b/hw/bsp/stm32h7/boards/stm32h750bdk/board.mk index d37a425fb..923c90753 100644 --- a/hw/bsp/stm32h7/boards/stm32h750bdk/board.mk +++ b/hw/bsp/stm32h7/boards/stm32h750bdk/board.mk @@ -15,7 +15,7 @@ SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32h750xx.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32h750xx_flash.icf # For flash-jlink target -JLINK_DEVICE = stm32h750xb_m7 +JLINK_DEVICE = stm32h750xb # flash target using on-board stlink flash: flash-stlink diff --git a/hw/bsp/stm32h7/family.c b/hw/bsp/stm32h7/family.c index adeb38e74..c81437958 100644 --- a/hw/bsp/stm32h7/family.c +++ b/hw/bsp/stm32h7/family.c @@ -102,9 +102,6 @@ void board_init(void) { trace_etm_init(); - // Enable UART Clock - UART_CLK_EN(); - #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); @@ -136,7 +133,10 @@ void board_init(void) { GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); +#ifdef UART_DEV // Uart + UART_CLK_EN(); + GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; @@ -153,6 +153,7 @@ void board_init(void) { UartHandle.Init.Mode = UART_MODE_TX_RX; UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&UartHandle); +#endif #if BOARD_TUD_RHPORT == 0 // Despite being call USB2_OTG @@ -280,8 +281,13 @@ int board_uart_read(uint8_t *buf, int len) { } int board_uart_write(void const *buf, int len) { +#ifdef UART_DEV HAL_UART_Transmit(&UartHandle, (uint8_t * )(uintptr_t) buf, len, 0xffff); +#else + (void) buf; +#endif + return len; } diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index 5c7e5e688..cfd0c81a8 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -1,58 +1,58 @@ -| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | ESP32-P4 | ST F407/411/429 FS | ST F407/429 HS | ST F412/767 FS | ST F723 FS | ST F723 HS | ST F769 | ST H743 HS | ST L476 FS | ST U5A5 HS | GD32VF103 FS | XMC4500 | -|:---------------------------|:----------------|:-------------|:--------------|:-------------|:---------------------|:-----------------|:-----------------|:-------------|:-------------|:-------------|:-------------|:-------------|:-------------|:---------------|:-------------| -| GUID | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | -| GSNPSID | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | -| - specs version | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | -| GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | -| GHWCFG2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | -| - op_mode | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | -| - arch | DMA internal | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | Slave only | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | DMA internal | -| - p2p (hub support) | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | -| - hs_phy_type | UTMI+ | n/a | n/a | UTMI+/ULPI | n/a | ULPI | n/a | n/a | UTMI+/ULPI | ULPI | ULPI | n/a | UTMI+ | n/a | n/a | -| - fs_phy_type | Dedicated | Dedicated | Dedicated | Shared ULPI | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | n/a | n/a | Dedicated | -| - num_dev_ep | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 | -| - num_host_ch | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 0 | 13 | -| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - mul_proc_intrpt | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - nptx_q_depth | 2 | 2 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - ptx_q_depth | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | -| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| GHWCFG3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | -| - xfer_size_width | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | -| - packet_size_width | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | -| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - i2c_enable | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | -| - vendor_ctrl_itf | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | -| - optional_feature_removed | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - synch_reset | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - otg_adp_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - battery_charger_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | -| - dfifo_depth | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 1006 | 952 | 512 | 952 | 0 | 634 | -| GHWCFG4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | -| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - enhanced_lpm_support | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - phy_data_width | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8 bit | 8/16 bit | -| - ctrl_ep_num | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - num_dev_in_eps | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 | -| - dma_desc_enable | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | -| - dma_desc_dynamic | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| | BCM2711 (Pi4) | EFM32GG | ESP32-S2/S3 | ESP32-P4 | ST F207/F407/411/429 FS | ST F407/429 HS | ST F412/767 FS | ST F723/L4P5 FS | ST F723 HS | ST F769 | ST H743/H750 | ST L476 FS | ST U5A5 HS | GD32VF103 | XMC4500 | +|:---------------------------|:----------------|:-------------|:--------------|:-------------|:--------------------------|:-----------------|:-----------------|:------------------|:-------------|:-------------|:---------------|:-------------|:-------------|:------------|:-------------| +| GUID | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | +| GSNPSID | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | +| - specs version | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | +| GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| GHWCFG2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | +| - op_mode | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | +| - arch | DMA internal | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | Slave only | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | DMA internal | +| - p2p (hub support) | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | +| - hs_phy_type | UTMI+ | n/a | n/a | UTMI+/ULPI | n/a | ULPI | n/a | n/a | UTMI+/ULPI | ULPI | ULPI | n/a | UTMI+ | n/a | n/a | +| - fs_phy_type | Dedicated | Dedicated | Dedicated | Shared ULPI | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | n/a | n/a | Dedicated | +| - num_dev_ep | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 | +| - num_host_ch | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 0 | 13 | +| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - mul_proc_intrpt | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - nptx_q_depth | 2 | 2 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - ptx_q_depth | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | +| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| GHWCFG3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | +| - xfer_size_width | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | +| - packet_size_width | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | +| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - i2c_enable | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | +| - vendor_ctrl_itf | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | +| - optional_feature_removed | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - synch_reset | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - otg_adp_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - battery_charger_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | +| - dfifo_depth | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 1006 | 952 | 512 | 952 | 0 | 634 | +| GHWCFG4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | +| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - enhanced_lpm_support | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - phy_data_width | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8 bit | 8/16 bit | +| - ctrl_ep_num | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - num_dev_in_eps | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 | +| - dma_desc_enable | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| - dma_desc_dynamic | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index ac32eb585..d1793a005 100755 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -10,20 +10,21 @@ import pandas as pd dwc2_reg_list = ['GUID', 'GSNPSID', 'GHWCFG1', 'GHWCFG2', 'GHWCFG3', 'GHWCFG4'] dwc2_reg_value = { 'BCM2711 (Pi4)': [0x2708A000, 0x4F54280A, 0, 0x228DDD50, 0xFF000E8, 0x1FF00020], - 'EFM32GG FS': [0, 0x4F54330A, 0, 0x228F5910, 0x1F204E8, 0x1BF08030], - 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0xC804B5, 0xD3F0A030], + 'EFM32GG': [0, 0x4F54330A, 0, 0x228F5910, 0x01F204E8, 0x1BF08030], + 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0x0C804B5, 0xD3F0A030], 'ESP32-P4': [0, 0x4F54400A, 0, 0x215FFFD0, 0x03805EB5, 0xDFF1A030], - 'ST F407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], - 'ST F407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], - 'ST F412/767 FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'ST F723 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'ST F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x3EED2E8, 0x23F00030], + 'ST F207/F407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x020001E8, 0x0FF08030], + 'ST F407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x03F403E8, 0x17F00030], + 'ST F412/767 FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030], + 'ST F723/L4P5 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030], + 'ST F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x03EED2E8, 0x23F00030], 'ST F769': [0x2100, 0x4F54320A, 0, 0x229FE190, 0x03EED2E8, 0x23F00030], - 'ST H743 HS': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x3B8D2E8, 0xE3F00030], # both HS cores - 'ST L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'ST H743/H750': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x03B8D2E8, 0xE3F00030], + 'ST L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030], 'ST U5A5 HS': [0x5000, 0x4F54411A, 0, 0x228FE052, 0x03B882E8, 0xE2103E30], - 'GD32VF103 FS': [0x1000, 0, 0, 0, 0, 0], - 'XMC4500': [0xAEC000, 0x4F54292A, 0, 0x228F5930, 0x27A01E5, 0xDBF08030] + 'GD32VF103': [0x1000, 0, 0, 0, 0, 0], + 'XMC4500': [0xAEC000, 0x4F54292A, 0, 0x228F5930, 0x027A01E5, 0xDBF08030] + } # Combine dwc2_info with dwc2_reg_list diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 60bba9bd2..0d7cae77e 100755 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -245,7 +245,7 @@ def test_dual_host_info_to_device_cdc(board): # for pico/pico2 make this test optional failed_msg = f'Enumerated devices {enum_dev_sn} not match with declared {declared_devs}' if 'raspberry_pi_pico' in board['name']: - print(f'\r\n {failed_msg} ', end='') + print(f'\r\n {failed_msg} {STATUS_FAILED} ', end='') else: assert False, failed_msg return 0 diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json index 2358c3c4f..44d4a617c 100644 --- a/test/hil/tinyusb.json +++ b/test/hil/tinyusb.json @@ -20,6 +20,13 @@ "flasher_sn": "000682804350", "flasher_args": "-device nrf52840_xxaa" }, + { + "name": "max32666fthr", + "uid": "0C81464124010B20FF0A08CC2C", + "flasher": "openocd_adi", + "flasher_sn": "E6614C311B597D32", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/max32665.cfg" + }, { "name": "metro_m4_express", "uid": "9995AD485337433231202020FF100A34", @@ -30,13 +37,6 @@ "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002130"}] } }, - { - "name": "max32666fthr", - "uid": "0C81464124010B20FF0A08CC2C", - "flasher": "openocd_adi", - "flasher_sn": "E6614C311B597D32", - "flasher_args": "-f interface/cmsis-dap.cfg -f target/max32665.cfg" - }, { "name": "lpcxpresso11u37", "uid": "17121919", @@ -82,6 +82,16 @@ "flasher_sn": "779541626", "flasher_args": "-device stm32f072rb" }, + { + "name": "stm32f407disco", + "uid": "30001A000647313332353735", + "build" : { + "flags_on": ["", "CFG_TUD_DWC2_DMA"] + }, + "flasher": "jlink", + "flasher_sn": "000773661813", + "flasher_args": "-device stm32f407vg" + }, { "name": "stm32f769disco", "uid": "21002F000F51363531383437", -- cgit v1.3.1 From 98e94a5d6d5dfd2bb468f3c2f4c9e82925fedd91 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 9 Oct 2024 21:47:23 +0700 Subject: enhance dwc2 --- hw/bsp/xmc4000/boards/xmc4500_relax/board.cmake | 1 + src/portable/synopsys/dwc2/dcd_dwc2.c | 135 ++++++++++-------------- src/portable/synopsys/dwc2/dwc2_type.h | 6 +- 3 files changed, 61 insertions(+), 81 deletions(-) diff --git a/hw/bsp/xmc4000/boards/xmc4500_relax/board.cmake b/hw/bsp/xmc4000/boards/xmc4500_relax/board.cmake index ec36bcc4d..e18741a9b 100644 --- a/hw/bsp/xmc4000/boards/xmc4500_relax/board.cmake +++ b/hw/bsp/xmc4000/boards/xmc4500_relax/board.cmake @@ -1,6 +1,7 @@ set(MCU_VARIANT XMC4500) set(JLINK_DEVICE XMC4500-1024) +#set(JLINK_OPTION "-USB 000551005307") set(LD_FILE_GNU ${SDK_DIR}/CMSIS/Infineon/COMPONENT_${MCU_VARIANT}/Source/TOOLCHAIN_GCC_ARM/XMC4500x1024.ld) function(update_board TARGET) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 99cf3fdaa..c0700633d 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -398,12 +398,8 @@ static void bus_reset(uint8_t rhport) { tu_memclr(xfer_status, sizeof(xfer_status)); _sof_en = false; - _allocated_ep_in_count = 1; - // clear device address - dwc2->dcfg &= ~DCFG_DAD_Msk; - // 1. NAK for all OUT endpoints for (uint8_t n = 0; n < ep_count; n++) { dwc2->epout[n].doepctl |= DOEPCTL_SNAK; @@ -419,13 +415,17 @@ static void bus_reset(uint8_t rhport) { dfifo_flush_tx(dwc2, 0x10); // all tx fifo dfifo_flush_rx(dwc2); - // 3. Set up interrupt mask + // 3. Set up interrupt mask for EP0 dwc2->daintmsk = TU_BIT(DAINTMSK_OEPM_Pos) | TU_BIT(DAINTMSK_IEPM_Pos); dwc2->doepmsk = DOEPMSK_STUPM | DOEPMSK_XFRCM; dwc2->diepmsk = DIEPMSK_TOM | DIEPMSK_XFRCM; + // 4. Set up DFIFO dfifo_init(rhport); + // 5. Reset device address + dwc2->dcfg &= ~DCFG_DAD_Msk; + // Fixed both control EP0 size to 64 bytes dwc2->epin[0].diepctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos); dwc2->epout[0].doepctl &= ~(0x03 << DOEPCTL_MPSIZ_Pos); @@ -907,7 +907,9 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t uint16_t const short_packet_size = total_bytes % xfer->max_size; // Zero-size packet is special case. - if (short_packet_size > 0 || (total_bytes == 0)) num_packets++; + if (short_packet_size > 0 || (total_bytes == 0)) { + num_packets++; + } // Schedule packets to be sent within interrupt edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); @@ -941,6 +943,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { // Interrupt Handler //-------------------------------------------------------------------- +// Process shared receive FIFO, this interrupt is only used in Slave mode static void handle_rxflvl_irq(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); volatile uint32_t const* rx_fifo = dwc2->fifo[0]; @@ -950,20 +953,8 @@ static void handle_rxflvl_irq(uint8_t rhport) { uint8_t const pktsts = (grxstsp & GRXSTSP_PKTSTS_Msk) >> GRXSTSP_PKTSTS_Pos; uint8_t const epnum = (grxstsp & GRXSTSP_EPNUM_Msk) >> GRXSTSP_EPNUM_Pos; uint16_t const bcnt = (grxstsp & GRXSTSP_BCNT_Msk) >> GRXSTSP_BCNT_Pos; - dwc2_epout_t* epout = &dwc2->epout[epnum]; -//#if CFG_TUSB_DEBUG >= DWC2_DEBUG -// const char * pktsts_str[] = -// { -// "ASSERT", "Global NAK (ISR)", "Out Data Received", "Out Transfer Complete (ISR)", -// "Setup Complete (ISR)", "ASSERT", "Setup Data Received" -// }; -// TU_LOG_LOCATION(); -// TU_LOG(DWC2_DEBUG, " EP %02X, Byte Count %u, %s\r\n", epnum, bcnt, pktsts_str[pktsts]); -// TU_LOG(DWC2_DEBUG, " daint = %08lX, doepint = %04X\r\n", (unsigned long) dwc2->daint, (unsigned int) epout->doepint); -//#endif - switch (pktsts) { // Global OUT NAK: do nothing case GRXSTS_PKTSTS_GLOBALOUTNAK: @@ -971,15 +962,14 @@ static void handle_rxflvl_irq(uint8_t rhport) { case GRXSTS_PKTSTS_SETUPRX: // Setup packet received - - // We can receive up to three setup packets in succession, but - // only the last one is valid. + // We can receive up to three setup packets in succession, but only the last one is valid. _setup_packet[0] = (*rx_fifo); _setup_packet[1] = (*rx_fifo); break; case GRXSTS_PKTSTS_SETUPDONE: - // Setup packet done (Interrupt) + // Setup packet done: + // After popping this out, dwc2 asserts a DOEPINT_SETUP interrupt which is handled by handle_epout_irq() epout->doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); break; @@ -1011,8 +1001,8 @@ static void handle_rxflvl_irq(uint8_t rhport) { } case GRXSTS_PKTSTS_OUTDONE: - /* Out packet done (Interrupt) - After this entry is popped from the receive FIFO, the controller asserts a Transfer Completed interrupt on + /* Out packet done + After this entry is popped from the receive FIFO, dwc2 asserts a Transfer Completed interrupt on the specified OUT endpoint which will be handled by handle_epout_irq() */ break; @@ -1034,51 +1024,56 @@ static void handle_epout_irq(uint8_t rhport) { const uint32_t doepint = epout->doepint; TU_ASSERT((epout->doepint & DOEPINT_AHBERR) == 0, ); + TU_LOG1_HEX(doepint); + + // Setup and/or STPKTRX/STSPHSRX (from 3.00a) can be set along with XFRC, and also set independently. + if (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a) { + if (doepint & DOEPINT_STSPHSRX) { + // Status phase received for control write: In token received from Host + epout->doepint = DOEPINT_STSPHSRX; + } + + if (doepint & DOEPINT_STPKTRX) { + // New setup packet received, but wait for Setup done, since we can receive up to 3 setup consecutively + epout->doepint = DOEPINT_STPKTRX; + } + } + + if (doepint & DOEPINT_SETUP) { + epout->doepint = DOEPINT_SETUP; + + if(dma_enabled(dwc2)) { + dma_setup_prepare(rhport); + } + + dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true); + } + // OUT XFER complete if (doepint & DOEPINT_XFRC) { epout->doepint = DOEPINT_XFRC; - xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); + // only handle data skip if it is setup or status related + // Normal OUT transfer complete + if (!(doepint & (DOEPINT_SETUP | DOEPINT_STPKTRX | DOEPINT_STSPHSRX))) { + xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); - if(dma_enabled(dwc2)) { - if (doepint & DOEPINT_SETUP) { - // STPKTRX is only available for version from 3_00a - if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_DMA_STPKTRX; - } - } else if (doepint & DOEPINT_STSPHSRX) { - epout->doepint = DOEPINT_STSPHSRX; - } else { - if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_DMA_STPKTRX; + if(dma_enabled(dwc2)) { + if ((epnum == 0) && ep0_pending[TUSB_DIR_OUT]) { + // EP0 can only handle one packet Schedule another packet to be received. + edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); } else { - // EP0 can only handle one packet - if ((epnum == 0) && ep0_pending[TUSB_DIR_OUT]) { - // Schedule another packet to be received. - edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); - } else { - // Fix packet length - uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; - xfer->total_len -= remain; - // this is ZLP, so prepare EP0 for next setup - if(epnum == 0 && xfer->total_len == 0) { - dma_setup_prepare(rhport); - } - - dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true); + // Fix packet length + uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; + xfer->total_len -= remain; + // this is ZLP, so prepare EP0 for next setup + if(epnum == 0 && xfer->total_len == 0) { + dma_setup_prepare(rhport); } + + dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true); } - } - } else { - // DMA_STPKTRX should only be set in Buffer DMA Mode. However, STM32L476 (slave-only) with v3.10a - // incorrectly set this along with SETUP bit. This may (or not) be STM32L476 or 3.10a specific bug - if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { - epout->doepint = DOEPINT_DMA_STPKTRX; } else { - if ((doepint & DOEPINT_STSPHSRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { - epout->doepint = DOEPINT_STSPHSRX; - } - // EP0 can only handle one packet if ((epnum == 0) && ep0_pending[TUSB_DIR_OUT]) { // Schedule another packet to be received. @@ -1089,19 +1084,6 @@ static void handle_epout_irq(uint8_t rhport) { } } } - - // SETUP packet Setup Phase done. - if (doepint & DOEPINT_SETUP) { - epout->doepint = DOEPINT_SETUP; - if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_DMA_STPKTRX; - } - if(dma_enabled(dwc2) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - dma_setup_prepare(rhport); - } - - dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true); - } } } } @@ -1274,13 +1256,10 @@ void dcd_int_handler(uint8_t rhport) { // RxFIFO non-empty interrupt handling. if (int_status & GINTSTS_RXFLVL) { // RXFLVL bit is read-only - - // Mask out RXFLVL while reading data from FIFO - dwc2->gintmsk &= ~GINTMSK_RXFLVLM; + dwc2->gintmsk &= ~GINTMSK_RXFLVLM; // disable RXFLVL interrupt while reading do { - // Loop until all available packets were handled - handle_rxflvl_irq(rhport); + handle_rxflvl_irq(rhport); // read all packets } while(dwc2->gintsts & GINTSTS_RXFLVL); dwc2->gintmsk |= GINTMSK_RXFLVLM; diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index d5a51fb09..cf05bbfec 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -1954,9 +1954,9 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define DOEPINT_NYET_Msk (0x1UL << DOEPINT_NYET_Pos) // 0x00004000 #define DOEPINT_NYET DOEPINT_NYET_Msk // NYET interrupt -#define DOEPINT_DMA_STPKTRX_Pos (15U) -#define DOEPINT_DMA_STPKTRX_Msk (0x1UL << DOEPINT_DMA_STPKTRX_Pos) // 0x00008000 -#define DOEPINT_DMA_STPKTRX DOEPINT_DMA_STPKTRX_Msk // Setup Packet Received in Buffer DMA Mode +#define DOEPINT_STPKTRX_Pos (15U) +#define DOEPINT_STPKTRX_Msk (0x1UL << DOEPINT_STPKTRX_Pos) // 0x00008000 +#define DOEPINT_STPKTRX DOEPINT_STPKTRX_Msk // Setup Packet Received /******************** Bit definition for DOEPTSIZ register ********************/ #define DOEPTSIZ_XFRSIZ_Pos (0U) -- cgit v1.3.1 From c3437961b8a9d65ca9efb2f6e22504cf1c695637 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 10 Oct 2024 00:04:29 +0700 Subject: remove stm32f769disco since it is not reliable --- examples/device/cdc_dual_ports/skip.txt | 2 ++ test/hil/tinyusb.json | 18 +++++++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 examples/device/cdc_dual_ports/skip.txt diff --git a/examples/device/cdc_dual_ports/skip.txt b/examples/device/cdc_dual_ports/skip.txt new file mode 100644 index 000000000..75184e5e5 --- /dev/null +++ b/examples/device/cdc_dual_ports/skip.txt @@ -0,0 +1,2 @@ +board:stm32f407disco +board:stm32f411disco diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json index 44d4a617c..2313f5d13 100644 --- a/test/hil/tinyusb.json +++ b/test/hil/tinyusb.json @@ -92,6 +92,15 @@ "flasher_sn": "000773661813", "flasher_args": "-device stm32f407vg" }, + { + "name": "stm32g0b1nucleo", + "uid": "4D0038000450434E37343120", + "flasher": "openocd", + "flasher_sn": "066FFF495087534867063844", + "flasher_args": "-f interface/stlink.cfg -f target/stm32g0x.cfg" + } + ], + "boards-skip": [ { "name": "stm32f769disco", "uid": "21002F000F51363531383437", @@ -102,15 +111,6 @@ "flasher_sn": "000778170924", "flasher_args": "-device stm32f769ni" }, - { - "name": "stm32g0b1nucleo", - "uid": "4D0038000450434E37343120", - "flasher": "openocd", - "flasher_sn": "066FFF495087534867063844", - "flasher_args": "-f interface/stlink.cfg -f target/stm32g0x.cfg" - } - ], - "boards-skip": [ { "name": "mimxrt1015_evk", "uid": "DC28F865D2111D228D00B0543A70463C", -- cgit v1.3.1 From ba3a5b437444881659881bb299ac999292c911ab Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 10 Oct 2024 10:48:25 +0700 Subject: clion files --- .idea/cmake.xml | 8 +++++--- .idea/runConfigurations/k64f.xml | 10 ++++++++++ .idea/runConfigurations/ra2a1.xml | 10 ++++++++++ .idea/runConfigurations/stlink.xml | 4 ++-- .idea/runConfigurations/stm32g474.xml | 5 +++-- .idea/runConfigurations/stm32h563.xml | 11 +++++++++++ .idea/runConfigurations/stm32h743.xml | 5 +++-- .idea/runConfigurations/stm32u5a5.xml | 11 +++++++++++ 8 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 .idea/runConfigurations/k64f.xml create mode 100644 .idea/runConfigurations/ra2a1.xml create mode 100644 .idea/runConfigurations/stm32h563.xml create mode 100644 .idea/runConfigurations/stm32u5a5.xml diff --git a/.idea/cmake.xml b/.idea/cmake.xml index d4ad3a748..c0b55a82e 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -87,14 +87,15 @@ - - - + + + + @@ -132,6 +133,7 @@ + diff --git a/.idea/runConfigurations/k64f.xml b/.idea/runConfigurations/k64f.xml new file mode 100644 index 000000000..80ca22d40 --- /dev/null +++ b/.idea/runConfigurations/k64f.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/ra2a1.xml b/.idea/runConfigurations/ra2a1.xml new file mode 100644 index 000000000..cb87de5bd --- /dev/null +++ b/.idea/runConfigurations/ra2a1.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/stlink.xml b/.idea/runConfigurations/stlink.xml index 628f7910d..2d94e66d6 100644 --- a/.idea/runConfigurations/stlink.xml +++ b/.idea/runConfigurations/stlink.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/stm32g474.xml b/.idea/runConfigurations/stm32g474.xml index 6d65e83c7..c3b5c9953 100644 --- a/.idea/runConfigurations/stm32g474.xml +++ b/.idea/runConfigurations/stm32g474.xml @@ -1,7 +1,8 @@ - - + + +